accept 得到的socket 是阻塞的还是非阻塞的

visualassist4680 2010-07-15 09:50:26
sockaccept = accept(socketlisten);
sockaccept 是阻塞的socket 还是 非阻塞的socket,或者说在什么情况下是阻塞的socket,什么情况下是非阻塞的
socketlisten 是阻塞还是非阻塞对 sockaccept 有什么影响.谢谢
...全文
12978 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
ngnhwan 2012-06-16
  • 打赏
  • 举报
回复 1
今天我也遇到和楼主差不多的疑惑,accept返回的socket是阻塞的还是非阻塞的?
我是在windwos xp上测试的,结果和accept对应的socket有关系,如果accept传入的socket是阻塞的那么返回的socket如果是正确的就是阻塞的,反之如果传入accept的socket是非阻塞的那么就是非阻塞的。
我的程序是一个简单的转发,想设置accept的超时,所以设置了传入accept的socket是非阻塞的,结果测试发现accept返回的socket发送send数据总是有10035错误;如果accept传入的socket不是非阻塞的,就没有这个问题,所以我觉得与传入accept的socket是否阻塞有关系;
以后有空用boost asio来替代,呵呵
Jarvan89 2012-01-06
  • 打赏
  • 举报
回复
感觉16楼说的很清楚
酒鬼 2011-05-30
  • 打赏
  • 举报
回复
呵呵,真的哎,要是listen的那个socket设为非阻塞的,accept返回的那个socket在不手动修改的情况下也就也已经是非阻塞的了。
listen的socket设为非阻塞后,accept返回的socket在没接到连接的时候值大小为INVALID_SOCKET,(无符号整型,32位1)。获取上次WSA错误返回值也是10035,形式类似recv
酒鬼 2011-05-30
  • 打赏
  • 举报
回复
测试结果返回的这个socket也是阻塞的,同其他socket默认形式相同。(xp,vs08)recv函数一直卡在那。
当手动设置后,即可:
newconnection =accept(listeningSocket,(SOCKADDR *)&clientAddr, &len);
u_long ulFlag = 1;
ioctlsocket(newconnection,FIONBIO,&ulFlag);//过后recv就直接返回了
返回值-1,WSAGetLastError()返回值10035,即WSAEWOULDBLOCK,
我也学习中,顺便测试下。呵呵,
酒鬼 2011-05-30
  • 打赏
  • 举报
回复
其实这些可以自己测试下嘛,如果有时间。。
jingnian1212 2010-12-29
  • 打赏
  • 举报
回复 3
我来回答一下这个问题。。。
首先在创建socket,,然后绑定什么就不说了,,,然后listen 监听前面创建的socket(你可以把listen当然是后台运行的监控一样)

listen语句之后一般会有accept。这个是接受连接请求的。
当监听到有连接请求来的时候,,,accept就会 重新创建一个socket(注意,该socket才是真正用来通信的)。。。。。。。

到这里楼主可明白了。。。。前面自己创建的socket只是用来listen(监听)的。。只有当监听到有连接请求时,并且accept函数接受了连接,才会创建一个新的socket。。这个新建的是用来通信的(明白)


那阻塞与非阻塞是什么情况呢? 这个只是针对accept来有意义。就是说,默认情况下,accept函数是阻塞的,就是说,在没有新连接请求来的情况下(listen监听),accept一直在这里等,函数没有返回,也就是说,卡在这个地方而不会创建新的socket,程序不会往下运行。。一旦有连接请求过来,则马上答应连接,并自行创建一个新socket,accept的返回值就是socket这值。相当于文件描述符性质。。。。

非阻塞,用户可以设置(fcntl函数), 这种情况下,accept函数,在没有连接请求来的情况下,马上会返回,也就是说不会在这里等,程序就会往下运行,返回值会一个负数。也就是说socket没有创建成功。。。。

总的来说,用来通信的socket 是accept函数的返回值,只有真连接来的时候,accept才会返回一个正确的值,这个返回值就是socket的描述符。

阻塞情况下,,没有连接请求来的时候,一直卡在这里,不会有返回值,也就没有创建socket,直到有请求。
非阻塞情况下,不管你有没有连接来,返正accept函数会马上执行完,并返回一个值。。当没有请求时,返回的是负数,也就是说这个socket是错误的,不可用。有请求的时候返回正数,这个就是socket描述符。
zuiyuezhou888 2010-07-16
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 zuiyuezhou888 的回复:]
引用 10 楼 initialj 的回复:

引用 8 楼 zuiyuezhou888 的回复:
引用 5 楼 visualassist4680 的回复:
谢谢楼上诸位,
我想知道的是,accept 返回有效值 socket 这个socket 工作在什么模式,是阻塞还是非阻塞模式.
楼上几位有点答非所问
1.2楼,我知道什么是阻塞模式什么是非阻塞模式
3.4楼,我问的不是 acce……
[/Quote]
呵呵 没理解 学习了
InitialJ 2010-07-15
  • 打赏
  • 举报
回复
SOCKET accept(
__in SOCKET s,
__out struct sockaddr* addr,
__inout int* addrlen
);
阻塞或者非阻塞都会接收,但是如果__in SOCKET s,是非阻塞的话,accept就是非阻塞模式,vice versa
zuiyuezhou888 2010-07-15
  • 打赏
  • 举报
回复
阻塞与非阻塞 这得看你使用什么模式
The accept function can block the caller until a connection is present if no pending connections are present on the queue, and the socket is marked as blocking. If the socket is marked as nonblocking and no pending connections are present on the queue, accept returns an error as described in the following. After the successful completion of accept returns a new socket handle, the accepted socket cannot be used to accept more connections. The original socket remains open and listens for new connection requests.

该函数可以接受一个连接阻塞,直到对方存在,如果没有连接上等待队列现在,套接字是阻塞显着。如果套接字被标记为非阻塞并没有挂起的连接在队列目前,接受返回一个错误,如下所述。后接受成功完成返回一个新的套接字句柄,不能接受的插座用于接受更多的连接。原始套接字仍然开放和新的连接请求侦听。
Normandie007 2010-07-15
  • 打赏
  • 举报
回复
阻塞和非阻塞 
  阻塞函数在完成其指定的任务以前不允许程序调用另一个函数。例如,程序执行一个读数据的函数调用时,在此函数完成读操作以前将不会执行下一程序语句。当服务器运行到accept语句时,而没有客户连接服务请求到来,服务器就会停止在accept语句上等待连接服务请求的到来。这种情况称为阻塞(blocking)。而非阻塞操作则可以立即完成。比如,如果你希望服务器仅仅注意检查是否有客户在等待连接,有就接受连接,否则就继续做其他事情,则可以通过将Socket设置为非阻塞方式来实现。非阻塞socket在没有客户在等待时就使accept调用立即返回。
  #include
  #include
  ……
sockfd = socket(AF_INET,SOCK_STREAM,0);
fcntl(sockfd,F_SETFL,O_NONBLOCK);


摘自http://linux.chinaunix.net/bbs/thread-798229-1-1.html
kemee 2010-07-15
  • 打赏
  • 举报
回复
这个不管是阻塞还是非阻塞他都得accept啊,什么情况是阻塞你自己定义的socket会不明白?
hastings 2010-07-15
  • 打赏
  • 举报
回复
..........................
lz其他的MSDN摘录回复不看的?
zuiyuezhou888 2010-07-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 initialj 的回复:]

引用 8 楼 zuiyuezhou888 的回复:
引用 5 楼 visualassist4680 的回复:
谢谢楼上诸位,
我想知道的是,accept 返回有效值 socket 这个socket 工作在什么模式,是阻塞还是非阻塞模式.
楼上几位有点答非所问
1.2楼,我知道什么是阻塞模式什么是非阻塞模式
3.4楼,我问的不是 accept 的工作模式,我知道 accept 可以工作……
[/Quote]
返回值sockaccept,是阻塞还是非阻塞???返回值还有这么一说???头一次听说
recv()是阻塞 没有听过recv()的返回值是阻塞的
jogger007 2010-07-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 visualassist4680 的回复:]
谢谢楼上诸位,
我想知道的是,accept 返回有效值 socket 这个socket 工作在什么模式,是阻塞还是非阻塞模式.
楼上几位有点答非所问
1.2楼,我知道什么是阻塞模式什么是非阻塞模式
3.4楼,我问的不是 accept 的工作模式,我知道 accept 可以工作在这两种模式
[/Quote]

阻塞的
visualassist4680 2010-07-15
  • 打赏
  • 举报
回复
把分给了看明白问题的人
zuiyuezhou888 2010-07-15
  • 打赏
  • 举报
回复
给你本书看看吧
windows网络编程技术
http://download.csdn.net/source/2544889
看看第七八章
zuiyuezhou888 2010-07-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 visualassist4680 的回复:]
谢谢楼上诸位,
我想知道的是,accept 返回有效值 socket 这个socket 工作在什么模式,是阻塞还是非阻塞模式.
楼上几位有点答非所问
1.2楼,我知道什么是阻塞模式什么是非阻塞模式
3.4楼,我问的不是 accept 的工作模式,我知道 accept 可以工作在这两种模式
[/Quote]
不知道LZ有没有仔细看我回复的内容
accept当你使用阻塞模式 当程序运行到accept他也会阻塞(程序停在这里等待) 相反当你使用……
阻塞就是程序运行到这里就停下来等待函数返回 明白??
hastings 2010-07-15
  • 打赏
  • 举报
回复
顶4楼~~~~
你可以看一下MSDN文档:
Remarks
The accept function extracts the first connection on the queue of pending connections on socket s. It then creates and returns a handle to the new socket. The newly created socket is the socket that will handle the actual connection; it has the same properties as socket s, including the asynchronous events registered with the WSAAsyncSelect or WSAEventSelect functions.
InitialJ 2010-07-15
  • 打赏
  • 举报
回复
新创建的socket 默认是阻塞的
visualassist4680 2010-07-15
  • 打赏
  • 举报
回复
谢谢楼上诸位,
我想知道的是,accept 返回有效值 socket 这个socket 工作在什么模式,是阻塞还是非阻塞模式.
楼上几位有点答非所问
1.2楼,我知道什么是阻塞模式什么是非阻塞模式
3.4楼,我问的不是 accept 的工作模式,我知道 accept 可以工作在这两种模式
网络编程,当然要用到Windows Socket(套接字)技术。Socket相关的操作由一系列API函数来完成,比如socket、bind、listen、connect、accept、send、sendto、recv、recvfrom等。调用这些API函数有一定的先后次序,有些函数的参数还比较复杂,对于开发者来说,不是很好用。于是,微软的MFC提供了两个类:CAsyncSocket和CSocket,极大地方便了Socket功能的使用。   CAsyncSocket类在较低层次上封装了Windows Socket API,并且通过内建一个(隐藏的)窗口,实现了适合Windows应用的异步机制(Windows Socket API默认情况下工作在阻塞模式,不方便直接在消息驱动的Windows程序上使用)。CSocket类从CAsyncSocket类派生,进一步简化了Socket功能的应用。不过很遗憾,正因为这两个类都内建了一个窗口,它们并不是线程安全的(thread-safe);如果要在多线程环境下应用Socket功能,建议自行封装Socket API函数。 基于TCP的socket编程的服务器端程序流程如下: 1、创建套接字 2、将套接字绑定到一个本地地址和端口号上(bind) 3、将套接字设为监听模式,准备接受客户请求(listen) 4、等待客户请求,请求到来时接受请求,建立链接,并返回 一个新的基于此次通信的套接字(accept) 5、用返回的套接字和客户端进行通信(send、recv) 6、返回,等待另一客户请求 7、关闭套接字 基于TCP的socket编程的客户端程序流程如下: 1、创建套接字 2、向服务器端发送请求(connect) 3、和服务器端进行通信(send、recv) 4、关闭套接字 基于UDP的socket编程的服务器端程序流程如下: 1、创建套接字 2、将套接字绑定到本地地址和端口号上(bind) 3、等待接收数据(recvfrom) 4、关闭套接字 基于UDP的socket编程的客户端程序流程如下: 1、创建套接字 2、和服务器端进行通信(sendto) 3、关闭套接字 异步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而同步指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式。   阻塞套接字是指执行此套接字的网络调用时,直到成功才返回,否则一直阻塞在此网络调用上,比如调用recv()函数读取网络缓冲区中的数据,如果没有数据到达,将一直挂在recv()这个函数调用上,直到读到一些数据,此函数调用才返回;而阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用recv()函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。在实际Windows网络通信软件开发中,异步阻塞套接字是用的最多的。平常所说的C/S(客户端/服务器)结构的软件就是异步阻塞模式的。   对于这些概念,初学者的理解也许只能似是而非,我将用一个最简单的例子说明异步阻塞Socket的基本原理和工作机制。目的是让初学者不仅对Socket异步阻塞的概念有个非常透彻的理解,而且也给他们提供一个用Socket开发网络通信应用程序的快速入门方法。操作系统是Windows 98(或NT4.0),开发工具是Visual C++6.0。   MFC提供了一个异步类CAsyncSocket,它封装了异步、阻塞Socket的基本功能,用它做常用的网络通信软件很方便。但它屏蔽了Socket的异步、阻塞等概念,开发人员无需了解异步、阻塞Socket的原理和工作机制。因此,建议初学者学习编网络通信程序时,暂且不要用MFC提供的类,而先用Winsock2 API,这样有助于对异步、阻塞Socket编程机制的理解。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧