如下的 code 为什么 不能 连续发送 ??       while(1)       {
           WSAResetEvent(h1);              // 等待 网络事件
           DWORD r2 =   WSAWaitForMultipleEvents(1, EventArray,FALSE,WSA_INFINITE,FALSE);
    
       WSANETWORKEVENTS  NetworkEvents;           // 获得 网络事件
   WSAEnumNetworkEvents(s1,h1,&NetworkEvents);
        if(NetworkEvents.lNetworkEvents & FD_WRITE )
         { 
    char data[100]={"hello socket"};
  send(s1,data,100,0); 
 
        }
     }   ////////// 运行以上code的现象是:  第一次 是可以 发送的 ,   while 执行 第 2 次的 时候 就会 永远 阻塞在  WSAWaitForMultipleEvents 函数的 地方 
 请问这是为什么?? 谢谢

解决方案 »

  1.   


     lixiaosan(小三)  , 你好:我前面的code 大概 是这样的
    SOCKET s1 = socket(AF_INET,STREAM , 0);HANDLE h1 = WSACreateEvent();WSAEventSelect(s1,h1.FD_WRITE);HANDLE EventArray[1]  = h1;
    while(1)
    {
    //
    // 加上这一句 主要是因为 觉得,每次WSAWaitForMultipleEvents 返回
    //
    // 会把 那个 event h1 置为 signaled 状态,所以 给他 复位一下
    //
    WSAResetEvent(h1); // }
     
    再帮忙分析一下,谢谢
      

  2.   

    哦。。你第一句就是WSAResetEvent,,我看掉了,以为你没有用WSAResetEvent。抱歉。。
      

  3.   

    是不是重置的时候index不对?http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsawaitformultipleevents_2.asp
    看看WSAWaitForMultipleEvents的返回值的处理HANDLE EventArray[1] = h1;
    ==>
    WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];EventArray[1] = WSACreateEvent();  DWORD dwIndex;
    dwIndex = WSAWaitForMultipleEvents(。);
    dwIndex -= WSA_WAIT_EVENT_0;//注意这里WSAResetEvent(EventArray[dwIndex]);
      

  4.   

    lixiaosan(小三)  , 你好: 我的code很简单,是 client 端的 , 就是我贴出来的那些, 就 1 个 event 和 1 个 socket  ,  因此直接 把 event 的 句柄 h1  传给 WSAResetEvent 函数 我的问题是, 为什么 WSAWaitForMultipleEvents 无法 返回了                 ( 我使用的 WSA_INFINITE 无线等待), 这样 我无法得到 error code ,  谢谢
      

  5.   

    为什么 第2次  FD_WRITE 的 状态 等不到呢  ?
      

  6.   

    WSAResetEvent(h1);  ///////////////////////////
    WSAResetEvent(EventArray[0]);应该复位以传信的事件发现你没有把事件数组和单个事件结合起来写成DWORD dwIndex;
    dwIndex = WSAWaitForMultipleEvents(。);
    dwIndex -= WSA_WAIT_EVENT_0;//注意这里WSAResetEvent(EventArray[dwIndex]);这个方式比较好
      

  7.   

    send返回WSAEWOULDBLOCK了吗?如果没有返回WSAEWOULDBLOCK那么不再收到FD_WRITE是正常的,不一定非要等待FD_WRITE作为发送数据的前提吧?
      

  8.   

    WSAWaitForMultipleEvents这个函数不能自动重置,你要手工重置
      

  9.   


    jazy() ( ) 信誉:100
    send返回WSAEWOULDBLOCK了吗?如果没有返回WSAEWOULDBLOCK那么不再收到FD_WRITE是正常的,不一定非要等待FD_WRITE作为发送数据的前提吧?
    =========================================================   你好:   按照你的方法,   我试了一下,可以了发送了,   但是 如何知道 发送走了 多少字节呢 ?   另外,按照同样的顺序, 如果 调用 recv 函数 那如何知道 到底收到多少数据呢?   因为 recv 的 返回值 是 实际 收到的 字节数,  但是 在异步情况下, 返回值 是 SOCKET_ERROR ,   这样就没有办法知道 recv 到底 收到了 多少字节数据了?  谢谢
     
      

  10.   

    send:即使出现错误WSAEWOULDBLOCK,当次send还是会完全成功的,只不过在得到FD_WRITE事件前,不允许下次sendrecv返回SOCKET_ERROR?那么getlasterror看看错误原因吧,这种情况没见过。我的理解只要收到了FD_READ,recv就不该不成功的,奇怪。
      

  11.   


     jazy() ( )   
     
     你好: 根据网上的一些代码 和 我的 理解 ,关于 send 和 recv 有两种使用的 框架: 以 send 函数 为例 如下: 请你看一下是否正确 或者 存在 理解上的 问题,  我是有些不明白?
    //////////////////
    框架 1简述: 先 调用  send 函数, 再调用 WSAWaitForMultipleEvents  对网络事件进行等待
     
      
      int r = send( )
      if( r == SOCKET_ERROR )
       {
           r = WSAGetLastError() 
           if( r == WSAEWOULDBLOCK ) 
           {
               
               WSAWaitForMultipleEvents            WSANETWORKEVENTS  NetworkEvents;         WSAEnumNetworkEvents(s1,h1,&NetworkEvents);
            if(NetworkEvents.lNetworkEvents & FD_WRITE )
             { 
               //     执行到这里 说明 前面的 send 已经执行成功了   ,对吗 ??
     
            }
           }
        }//////////////////
    框架 2简述: 先 调用 WSAWaitForMultipleEvents  对网络事件进行等待  ,      待 出现  FD_WRITE 的 信息后 , 再 调用  send 函数
     
         
     
               
               WSAWaitForMultipleEvents            WSANETWORKEVENTS  NetworkEvents;         WSAEnumNetworkEvents(s1,h1,&NetworkEvents);
            if(NetworkEvents.lNetworkEvents & FD_WRITE )
             { 
      //     执行到这里 说明  此时 如果 此时 调用  send , os 保证 会成功    对吗 ??
                 int r = send( )
            }
           }
        } 谢谢
      

  12.   

    框架 2简述: 先 调用 WSAWaitForMultipleEvents  对网络事件进行等待  ,      待 出现  FD_WRITE 的 信息后 , 再 调用  send 函数这里我的理解与你不同,我看msdn的解释,连接建立后FD_WRITE一定处于signal状态,可以用send(就是说这第一次send之前等不等FD_WRITE是无所谓的),但这时send的结果不一定成功,
    (1)如果成功,马上就可以再用send,不需要也等不到下一个FD_WRITE。
    (2)如果失败且原因是block,就必须等下一个FD_WRITE,以决定是否可以进行下一次send。
    因此我认为你的两种框架需要组合在一起,并不存在并列的两种选择。