1. 
如果用完成端口
像 WSARecv  WSASend ConnectEx这些异步操作
如果立即完成,在GetQueuedCompletionStatus中能不能得到通知呢?
如果不能,就得在操作后马上检查,而且要作出相应处理,
如果这些操作是在其它线程中感觉很麻烦,不如在worker线程中统一处理好
2.用EventSelect的话
采用下面的逻辑有没有问题 
发送数据那里是不是有问题?
  bWritable = false;
 while(1){
   ret = WSAWaitForMultipleEvents(1, hSocketEvent, FALSE, 2000, FALSE );
   if(haveSomethingToWrite && bWritable){ //如果有数据要发,且可写
     for(int i=0;i<DataCount;i++)   //循环发送若干数据
     {
      int result = send(conn, buf, strlen(buf);  //这里是不是该用WSASend就没有下面的问题了?
      if( result==SOCKET_ERROR && WSAGetLastError()==WSAEWOULDBLOCK) //返回-1的话上面的send发送的数据最终能发送出去么?
      {
         bWritable = false;  //置为不可写
         break;
      }//if
     }//for
   }//if
   if(ret == timeout or WAIT_IO_COMPLETION ) continue;
   
   if( (evt.lNetworkEvents & FD_READ) ){
      recvsomething();
   }
   else if( evt.lNetworkEvents & FD_WRITE && evt.iErrorCode[FD_READ_BIT]==0)
   { 
      bWritable = true;
   }
   // other case... } //while

解决方案 »

  1.   

    对了,还有个问题,从测试结果来看
    当建立连接后能FD_WRITE事件,可以把bWritable置为true
    调用send 一但返回SOCKET_ERROR置为false后
    就没有FD_WRITE事件了,也就是bWritable一直为false
    这是什么原因呢
      

  2.   

    这里是不是该用WSASend就没有下面的问题了?
    这里与用send是一样的返回-1的话上面的send发送的数据最终能发送出去么?
    没有发送出去
      

  3.   

    Event那个代码不应该那么写,发送不要放在事件处理的线程里(不是不能,而是设计上的问题,很奇怪,而且没什么意义,如果没有事件触发就不发送了么?)WSAEWOULDBLOCK的时候发送没有成功,可以把数据缓存下来,FD_SEND的时候发送。性能要求不高的话可以sleep一下再重新发送。
    你这样实现,发送失败就相当于跳过了此次发送。