Socket向完成端口多次发送消息浅见

1.     同时发送多个WSARecv消息处理,多余的会有什么情况?

使用代码测试,显示结果为全部返回错误997,表示都可以正常发出recv操作,且多个工作线程同时在检测此socket的多个recv消息,运行片刻立即关闭Client端,发现工作线程出现的异常,1个或2个工作线程中的closesocket函数调用失败,错误码为10038,因此要尽力避免对同一个socket向完成端口发送重复的同一信息。在接受数据时并没有出现重复现象(内部有同步),也就是说只有在断开socket时会有很小不出错的可能,跟线程调度有关。

测试代码如下:Server端:

(侦听线程)

......

//成功与Client建立连接

while(1)
{

   while(WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
    &(PerIoData->Overlapped), NULL) ==SOCKET_ERROR && WSAGetLastError()    ==ERROR_IO_PENDING)
   {
    printf("WSARecv()2 failed with error %d/n", WSAGetLastError());

    Sleep(1000);
   }
   printf("WSARecv() succeed!/n");
   Sleep(5000);

}

......

 

(工作线程)

......

while(TRUE)
   {
      //完成端口有消息来了
      if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
         (LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)//PerIoData的其他数据成员由此函数在收到数据时填充
      {
   if(GetLastError() ==64)//套接字无效,有人掉线了
   {
    printf("Invalid socket %d was closed!/n", PerHandleData->Socket);
    if(closesocket(PerHandleData->Socket) ==SOCKET_ERROR)
    {
     printf("closesocket() failed with error %d/n", WSAGetLastError());
     return 0;
    }
    GlobalFree(PerHandleData);
    GlobalFree(PerIoData);
    printf("PerIoData at %d was freed!/n", PerIoData);
    continue;
   }
      }
   printf("GetQueuedCompletionStatus() 返回BytesTransferred ==%d/n", BytesTransferred);//------

   printf("PerIoData->DataBuf.buf ==%s/n", PerIoData->DataBuf.buf);

   printf("completion routine running---------/n");

}

Client端:

......

//connect成功与Server取得链接

while(1)
 {

  //获取键盘输入,并保存
  cin>>lpPerIoData->Buffer;
  lpPerIoData->DataBuf.buf =lpPerIoData->Buffer;
  lpPerIoData->DataBuf.len =DATA_BUFSIZE;

  //发送数据
  if(WSASend(Client, &(lpPerIoData->DataBuf), 1, &(lpPerIoData->BytesSEND),
   0, &(lpPerIoData->Overlapped), NULL) ==SOCKET_ERROR)
  {
   printf("WSASend() failed with error %d/n", WSAGetLastError());
   Sleep(1000);
   return;
  }
  else
   printf("Send Succeed!/n");

   Sleep(5000);
 }

 Server打印信息见图片。 

2.同时发送多个WSASend消息处理

由于是异步操作所以这个消息经常是立即成功返回0的,但是当完成端口内部的服务线程(不是指工作线程)有很多消息要处理的时候应该会返回997错误,因此WSASend消息是有可能被堆积在未完成消息队列里的,如果服务线程同时执行针对同一个socket的send操作"可能"(这里是我猜的)会引起数据的混乱,因此不应重复调用WSASend发送消息。

3.同时发送WSARecv和WSASend消息

这两者不冲突。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章