zoukankan      html  css  js  c++  java
  • 看到关于socket非阻塞模式设置方式记录一下。

    关于socket的阻塞与非阻塞模式以及它们之间的优缺点,这已经没什么可言的;我打个很简单的比方,如果你调用socket send函数时;

    如果是阻塞模式下:

    send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么 send就比较s的发送缓冲区的剩余空间和len,如果len大于剩余空间大小,send就一直等待协议把s的发送缓冲中的数据发送完,如果len小于剩余空间大小send就仅仅把buf中的数据copy到剩余空间里

    如果是非阻塞模式下:

    在调用socket send函数时,如果能写到socket缓冲区时,就写数据并返回实际写的字节数目,当然这个返回的实际值可能比你所要写的数据长度要小些(On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the client and server computers),如果不可写的话,就直接返回SOCKET_ERROR了,所以没有等待的过程。。

    经过上面的介绍后,下面介绍如何设置socket的非阻塞模式:

    当使用socket()函数和WSASocket()函数创建套接字时,默认都是阻塞的。在创建套接字之后,通过调用ioctlsocket()函数,将该套接字设置为非阻塞模式。

    //-------------------------

    // Set the socket I/O mode: In this case FIONBIO

    // enables or disables the blocking mode for the

    // socket based on the numerical value of iMode.

    // If iMode = 0, blocking is enabled;

    // If iMode != 0, non-blocking mode is enabled.

    u_long iMode = 1;  //non-blocking mode is enabled.

    ioctlsocket(m_socket, FIONBIO, &iMode); //设置为非阻塞模式

    套接字设置为非阻塞模式后,在调用Windows Sockets API函数时,调用函数会立即返回。大多数情况下,这些函数调用都会调用“失败”,并返回WSAEWOULDBLOCK错误代码。说明请求的操作在调用期间内没有时间完成。通常,应用程序需要重复调用该函数,直到获得成功返回代码。 不同的Windows Sockets API函数,在调用失败时返回的WSAEWOULDBLOCK错误代码具有不同的含义

    需要说明的是并非所有的 Windows Sockets API 在非阻塞模式下调用,都会返回 WSAEWOULDBLOCK 错误。例如,以非阻塞模式的套接字为参数调用 bind() 函数时,就不会返回该错误代码。当然,在调用 WSAStartup() 函数时更不会返回该错误代码,因为该函数是应用程序第一调用的函数,当然不会返回这样的错误代码。

    要将套接字设置为非阻塞模式,除了使用 ioctlsocket() 函数之外,还可以使用 WSAAsyncselect() 和 WSAEventselect() 函数。当调用该函数时,套接字会自动地设置为非阻塞方式:

    The WSAAsyncSelect function automatically sets socket s to nonblocking mode, regardless of the value of lEvent .

    The WSAEventSelect function automatically sets socket s to nonblocking mode, regardless of the value of lNetworkEvents .

  • 相关阅读:
    C# 根据主窗体的位置弹窗信息窗体一直保持在主窗体中间
    c# winForm父子窗口 通过委托进行信息传递
    使用devexpress插件 消除运行时弹窗
    C# 获取当前时间戳
    WinForm实现Loading等待界面
    转载 C#设置控件 Enabled 为 false 时背景色不改变
    DEV gridView中加入加载条显示进度,必须为圆角型
    winfrom 圆角化
    列表元素的反转、排序——python
    使用for循环和while循环打印九九乘法表——python
  • 原文地址:https://www.cnblogs.com/lidabo/p/3804267.html
Copyright © 2011-2022 走看看