zoukankan      html  css  js  c++  java
  • 非阻塞I/O

    通常情况下套接口是阻塞的,这意味着当一个套接字函数调用不能立即完成时,进程进入睡眠,知道操作完成。可能阻塞套接口的调用分为4种。

    1、输入:recv、recvfrom。当阻塞的tcp调用时,如果套接口缓冲区没有数据可读,进程将在数据到达前一直处于睡眠。同样如果一个阻塞的udp缓冲区为空,进程在下一个数据报到来前一直处于睡眠状态

    而非阻塞套接口不管是否有数据都将直接返回,有数据正常返回,没数据时WSAGetLastError()会返回WSAEWOULDBLOCK。

    2、输出:send、sendto。对一个tcp socket,内核从应用程序缓冲区想套接口缓冲区拷贝数据。当套接口没有空间时,进程处于睡眠,知道足够空间(windows xp下套接口的默认发送和接受缓冲区是8K,用getsockopt(m_sock, SOL_SOCKET, SO_RCVBUF,&iSize,&len)取得,也可以用setsockopt()设置缓冲区大小)。

    对于非阻塞tcp套接字,如果套接字缓冲区没有空间,输出返回SOCKET_ERROR,用WSAGetLastError()得到WSAEWOULDBLOCK。直到缓冲区有空间,返回内核向套接字缓冲区拷贝的字节数。

    udp套接口没有发送区,内核只是拷贝进程数据向协议栈的下层传递,加上udp与ip的头部。因此一个阻塞udp的socket的输出操作不会阻塞。

    3、接受外来连接:accept。如果一个阻塞套接口调用accept,而且没有新的连接,进程进入睡眠。在非阻塞接口调用accept,accept立即返回(有点疑义,后面补上)

    4、初始化连接:tcp的connect。(udp的connect并不建立真实连接,只是内核保存了对方ip和端口)tcp的连接建立包括3次握手过程,而且客户端在接收到其SYN的ACK前不会返回。就是说tcp connect至少会阻塞一次往返时间(RTT)。

    而在一个非阻塞的tcp套接口上调用connect,一般不能马上建立连接,返回SOCKET_ERROR,WSAGetLastError()得到WSAEWOULDBLOCK错,但是connect的三次握手继续进行。需要注意的是client与server在同一台电脑上时,连接可以马上建立。一般情况下需要注册通知事件:

    • select检查socket是否可写
    • WSAEventSelect的FD_CONNECT(这个没用过)

    简单讲,非阻塞socket一般与select模型一起使用。

  • 相关阅读:
    关于 self 和 super 在oc 中 的疑惑 与 分析
    面向对象总结
    OC面向对象的三大特征
    Web jsp开发学习——Servlet提交表单时用法
    Web jsp开发学习——Servlet提交表单时用法
    Web jsp开发学习——点击菜单页面切换
    Web jsp开发学习——点击菜单页面切换
    珍藏的数据库SQL基础练习题答案
    珍藏的数据库SQL基础练习题答案
    数据库SQL语言学习--上机练习3(插入 更新 删除)
  • 原文地址:https://www.cnblogs.com/littlejohnny/p/1921069.html
Copyright © 2011-2022 走看看