4

我正在研究基于 newtwork 事件的套接字应用程序。

当客户端发送了一些数据并且套接字上有要读取的内容时,会生成 FD_READ 网络事件。

现在根据我的理解,当服务器要通过套接字写入时,必须有一个事件产生,即FD_WRITE。但是这个消息是怎么产生的呢?

当有可读取的内容时,会自动生成 FD_READ,但是当服务器要写入内容时,FD_WRITE 呢?

谁能帮我解决这个困惑?

以下是代码片段:

WSAEVENT hEvent = WSACreateEvent();
WSANETWORKEVENTS events;
WSAEventSelect(newSocketIdentifier, hEvent, FD_READ | FD_WRITE);

   while(1)
      {   //while(1) starts
         waitRet = WSAWaitForMultipleEvents(1, &hEvent, FALSE, WSA_INFINITE, FALSE);
         //WSAResetEvent(hEvent);
         if(WSAEnumNetworkEvents(newSocketIdentifier,hEvent,&events) == SOCKET_ERROR)
            {
              //Failure
            }
     else
        {   //else event occurred starts
            if(events.lNetworkEvents & FD_READ)
            {
                            //recvfrom()   
            }
            if(events.lNetworkEvents & FD_WRITE)
            {
                 //sendto()
            }
        }
      }
4

1 回答 1

4

FD_WRITE 表示您现在可以写入套接字。如果发送缓冲区已满(您发送数据的速度比在网络上发送的速度要快),最终您将无法再写入,直到您稍等片刻。

一旦由于缓冲区已满而导致写入失败,此消息将发送给您,让您知道您可以重试该发送。

当您第一次打开套接字时也会发送它,让您知道它在那里并且您可以开始编写。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms741576(v=vs.85).aspx

FD_WRITE 网络事件的处理方式略有不同。FD_WRITE 网络事件在第一次通过调用connectConnectExWSAConnectWSAConnectByListWSAConnectByName函数连接套接字时,或者当使用acceptAcceptExWSAAccept函数接受套接字时,然后在发送失败后使用 WSAEWOULDBLOCK时记录并且缓冲区空间变得可用。因此,应用程序可以假设从第一个 FD_WRITE 网络事件设置开始发送是可能的,并持续到发送返回 WSAEWOULDBLOCK。在这样的失败之后,当记录 FD_WRITE 网络事件并设置关联的事件对象时,应用程序将发现再次可以发送。

因此,理想情况下,您现在可能会保留是否可以写作的标志。它开始时为 true,但最终,在调用sendto时会收到一个WSAEWOULDBLOCK,并将其设置为 false。收到FD_WRITE后,将标志设置回 true 并继续发送数据包。

于 2013-05-10T09:36:14.553 回答