TCP/IP总结1:阻塞socket和非阻塞socket

来源:互联网 发布:seo网站排名优化工具 编辑:程序博客网 时间:2024/04/29 17:11
序:前段时间狂看了很多关于网络编程的资料,这里自己总结一下,以便自己以后可以参考。


什么是阻塞socket,什么是非阻塞socket


    对于这个问题,我们要先弄清什么是阻塞/非阻塞。阻塞与非阻塞是对一个文件描述符指定的文件或设备的两种工作方式。 
   
    阻塞的意思是指,当试图对该文件描述符进行读写时,如果当时没有东西可读或者暂时不可写,程序就进入等待状态,直到有东


西可读或者可写为止。
   
    非阻塞的意思是,当没有东西可读或者不可写时,读写函数就马上返回,而不会等待。


    现在来理解什么是阻塞socket,什么是非阻塞socket。每个通过socket()函数创建的socket,本质就是一个文件描述符,所以对


该文件描述符的IO操作方式不同,就有了阻塞socket和非阻塞socket。


    那是不是说阻塞socket下的所以socket api函数都是阻塞的呢,如果你还不能正确的回答这个问题,说明上面简短的说明并没有


让你真正的明白什么是阻塞socket和非阻塞socket。这个问题的答案是否定的,为什么是否定的,因为并不是每个socket的api都会


涉及到对文件描述符的IO操作。


    这里我列举了,哪些socket api会阻塞:
    accept,connect,recv(recvfrom),send(sendto),closesocket,select(poll或epoll)
    
    accept在阻塞模式下,没有新连接时,线程会进入睡眠状态;非阻塞模式下,没有新连接时,立即返回WOULDBLOCK错误。


    connect在阻塞模式下,仅TCP连接建立成功或出错时才返回,分几种具体的情况,这里不再叙述;非阻塞模式下,该函数会立即


返回INPROCESS错误(需用select检测该连接是否建立成功)    


    recv/recvfrom/send/sendto很好理解,因为这两类函数读写socket文件描述符的接收/发送缓冲区。 


    select/poll/epoll并不是真正意义上的阻塞,它们的阻塞是由于它们最后一个timeout参数决定的,timeout大于0时,它们会一


直等待直到超时才退出(相等于阻塞了吧,^_^),而timeout=-1即永远等待。 


    closesocket也不是真正意义上的阻塞,它其实是指是否等待关闭(相当于阻塞了吧,^_^),它受套接字选项SO_LINGER和


SO_DONTLINGER的影响。若SO_DONTLINGER或SO_LINGER的间隔=0时,closesocket就是非等待关闭的,但是当SO_LINGER的间隔>0时,


closesoket就是等待关闭的,直到剩余数据都发送完毕或直到超时才退出。(但是这个地方只有对于阻塞的套接口才有用,如果是非


阻塞的套接口,它会立即返回并且指示错误WOULDBLOCK)。




    最后提供linux下和windows下设置阻塞和非阻塞的几种方式:
    linux:
           fcntl(socket, F_SETFL, flags | O_NONBLOCK);
           read/recv函数的最后一个参数也可以设置阻塞或非阻塞方式


    windows:
           ioctlsocket,WSAAsyncselect()和WSAEventselect()
  read/recv函数的最后一个参数也可以设置阻塞或非阻塞方式
原创粉丝点击