您的位置:首页 > 其它

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

2009-07-18 10:48 411 查看
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消息

这两者不冲突。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: