问题背景:客户端向服务器连续发送两个自定义的struct,服务器来接收
          客户端和服务器在同一台机器上时服务器接收正常,把客户
          端放在其他机器上时服务器接收出错通过GetLastError()和FormatMessage()两个函数检查到错误是
“无法立即完成一个非阻挡性套接字操作”,那么这个错误怎么解决
比较好呢?请各位给个意见。

解决方案 »

  1.   

    “无法立即完成一个非阻挡性套接字操作”it is not a mistake
      

  2.   

    一两句说不清楚。你用的什么?MFC?API?
      

  3.   

    发送用的是send(),接收用的是recv()
      

  4.   

    用的哪个模型?select ?WSAAsyncSelect?WSAEventSelect?
      

  5.   

    TO Bind(天高云淡):用的是WSAEventSelect+WSAWaitForMultipleEvents
      

  6.   

    用WSAWaitForMultipleEvents和WSAEnumNetworkEvents来判断FD_xxx事件。比如在send后错误代码为WSAEWOULDBLOCK,则系统会自动产生一次FD_WRITE事件。在响应这个事件的函数中,你可以继续调用send函数。
      

  7.   

    TO Bind(天高云淡):
    能不能给我讲一下产生这种错误的原因是什么?
    我的程序是在调用recv()时产生这种错误
    查了一下MSDN里面有这样一段话:
    This error is returned from operatons on non-blocking sockets that cannot be completed immediately, for example Receive when no data is queued to be read from the socket. It is a non-fatal error, and the operation should be retried later.好像是说因为Socket没有数据供读取,可是我的两个struct是连续发送的,
    而且第一个struct的接收是正确的,Socket中不可能没有数据啊
      

  8.   

    因为为阻塞模式下,函数不会等到操作完成,便会返回。这时表示操作尚未完成。返回值为SOCKET_ERROR,并且用WSAGetLastError获得的错误代码为WSAEWOULDBLOCK。这种模式的优点便是不会使得程序在傻等某一个IO操作完成(因为IO操作通常是比较慢的),便可继续执行后继操作。当IO操作完成后,系统会一种方式来通知程序。比如在WSAEventSelect模型中便是以事件方式来通知。在WSAAsyncSelect模型中便以窗口消息来通知等等所以,我们的程序就应提供这种机能,能够接收系统的这种通知。具体资料你可以在MSDN中搜索WSAAsyncSelect或WSAEventSelect。
      

  9.   

    另外:在recv时遇到WSAEWOULDBLOCK,通常表示此时系统缓冲中并没有可读的数据。
      

  10.   

    我前段也遇到过,好像是线程同步的事,你看看你代码中有没有这样的错。还有一个可能是,一方closesocket了。
      

  11.   

    肯定是你第一次 recv 的时候就已经把两个 struct 都读完了!
    这种事见的多了.
      

  12.   

    TO copy_paste(木石三) :
    能不能把你的解决办法说的更清楚一些呢?
    希望能向你请教这个问题
    能留给我你的mail吗?
    我的mail:[email protected]
      

  13.   

    to  wxhnet(思平):
    我的第一个struct的大小是已知的
    在recv()的时候我读的字节数正好是这个结构的大小
    不可能把两个一起读完的
      

  14.   

    http://expert.csdn.net/Expert/topic/1325/1325807.xml?temp=.5630457
    我的两个函数.关于调用send老是返回WOULDBLOCK.
      

  15.   

    FD_WRITE消息, MFC将其映射为ONSEND()函数。
    FD_WRITE表示,现在网络已经准备好发送数据了,所以大都在这个函数中才SEND()。当然,一般情况下随意地调用SEND()也很少出问题。
    2。关于什么时候有这个消息,取决于你是否调用了ASYNCSELECT()函数,如果你使用CASYNCSOCKET及CSOCKET类,默认情况下,CREATE()时它自动调用了ASYNCSELECT(FD_WRITE),于是连接建立后,ONSEND()就会被调用。ASYNCSELETE(FD_WRITE)表示,需要发送数据,系统接到这个请求后,在网络不忙的时候,就会调用ONSEND()。
    3。需要发送数据时,先将数据缓存起来,然后调用ASYNCSELECT(FD_WRITE);在ONSEND中发送缓存中的数据。
      

  16.   

    everandforever(Forever) 的思路可以借鉴一下
    我用的是Winsock而不是MFC,
    可以用WSAWaitForMultipleEvents和WSAEnumNetworkEvents
    判断FD_READ事件,然后处理这个事件
      

  17.   

    看看<<windows网络编程技术>>吧,应该能解决问题了.