服务端是IOCP模型,是我工作者线程处理时出问题了吗?工作者线程如下:
DWORD WINAPI CMySvr::WorkerThread(void *lpPara)
{
_stThreadParam_ *pParam =(_stThreadParam_ *)lpPara;
HANDLE CompletionPort=pParam->completePort;
CMySvr *pSvr = pParam->pSvr; DWORD BytesTransferred;
LPOVERLAPPED Overlapped;
LPPER_HANDLE_DATA PerHandleData;
IO_DATA* data;
DWORD SendBytes, RecvBytes;
DWORD Flags;
while(TRUE)
{
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &data, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
return 0;
}
// 检查数据传送完了吗
if (BytesTransferred == 0)
{
printf("Closing socket %d\n", PerHandleData->Socket);
if (closesocket(PerHandleData->Socket) == SOCKET_ERROR)
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
return 0;
}
GlobalFree(PerHandleData); //释放内存块。您必须传给该函数一个内存句柄。
GlobalFree(data);
continue;
}
if(data->opCode == IO_READ)
{
pSvr->RecvData(data,PerHandleData->Socket); //对接收到的信息进行处理,处理时会WSASend()
}
else if(data->opCode == IO_WRITE)
{
data->opCode = IO_READ;
RecvBytes = 0;
Flags = 0;
data->wsabuf.buf = data->Buffer,
ZeroMemory(data->wsabuf.buf,MAX_BUFF_SIZE);
data->Overlapped.Internal = 0;
data->Overlapped.InternalHigh = 0;
data->Overlapped.Offset = 0;
data->Overlapped.OffsetHigh = 0;
data->Overlapped.hEvent = NULL;
data->wsabuf.len = MAX_BUFF_SIZE;
int nRet = WSARecv(
PerHandleData->Socket,
&data->wsabuf, 1, &RecvBytes,
&Flags,
&data->Overlapped, NULL); //继续接收数据
if( nRet == SOCKET_ERROR && (ERROR_IO_PENDING != GetLastError()) )
{
cout << "WASRecv Failed::Reason Code::"<< GetLastError() << endl;
closesocket(PerHandleData->Socket);
delete data;
continue;
}
}
}
return 0;
}
DWORD WINAPI CMySvr::WorkerThread(void *lpPara)
{
_stThreadParam_ *pParam =(_stThreadParam_ *)lpPara;
HANDLE CompletionPort=pParam->completePort;
CMySvr *pSvr = pParam->pSvr; DWORD BytesTransferred;
LPOVERLAPPED Overlapped;
LPPER_HANDLE_DATA PerHandleData;
IO_DATA* data;
DWORD SendBytes, RecvBytes;
DWORD Flags;
while(TRUE)
{
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &data, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
return 0;
}
// 检查数据传送完了吗
if (BytesTransferred == 0)
{
printf("Closing socket %d\n", PerHandleData->Socket);
if (closesocket(PerHandleData->Socket) == SOCKET_ERROR)
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
return 0;
}
GlobalFree(PerHandleData); //释放内存块。您必须传给该函数一个内存句柄。
GlobalFree(data);
continue;
}
if(data->opCode == IO_READ)
{
pSvr->RecvData(data,PerHandleData->Socket); //对接收到的信息进行处理,处理时会WSASend()
}
else if(data->opCode == IO_WRITE)
{
data->opCode = IO_READ;
RecvBytes = 0;
Flags = 0;
data->wsabuf.buf = data->Buffer,
ZeroMemory(data->wsabuf.buf,MAX_BUFF_SIZE);
data->Overlapped.Internal = 0;
data->Overlapped.InternalHigh = 0;
data->Overlapped.Offset = 0;
data->Overlapped.OffsetHigh = 0;
data->Overlapped.hEvent = NULL;
data->wsabuf.len = MAX_BUFF_SIZE;
int nRet = WSARecv(
PerHandleData->Socket,
&data->wsabuf, 1, &RecvBytes,
&Flags,
&data->Overlapped, NULL); //继续接收数据
if( nRet == SOCKET_ERROR && (ERROR_IO_PENDING != GetLastError()) )
{
cout << "WASRecv Failed::Reason Code::"<< GetLastError() << endl;
closesocket(PerHandleData->Socket);
delete data;
continue;
}
}
}
return 0;
}
解决方案 »
- 有没有办法为窗口的标题栏换个指定的颜色,且最小/大化等按钮不被覆盖...(欢迎讨论)
- 打开多个非模态对话框, 现在我按下一个按钮就把全部非模态对话框关闭 马上给分!!
- 关于Install Shield for microsoft vc++6.0问题
- OnClick()事件不管用了,怎么辦?
- 如何编程实现 在“我的电脑”的目录下建一个目录。
- 在ATL中使用GetDlgItem返回一个错误的值是为什么,谢谢
- 请教,如何激活一个输入法?
- 请教:我想在DLL中使用对话框,要做什么工作?
- 请问VC++6.0MFC下的Project WorkSpace一但创建其最后修改日期就是创建时的时间,不能更改了?
- 请问在程序中如何关闭自己?
- 两个窗口切换问题?大虾们请进,急!
- 关于删除CComboBox的DeleteString()
GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &data, INFINITE) &data , 不出错才怪!
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &Overlapped, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
continue;
}
data=(IO_DATA *)Overlapped;
这样可以吗?
还是个野指针
改成 POVERLAPPED Overlapped;
是因为没初始化吗?
那改成LPOVERLAPPED Overlapped=NULL;可以吗?
delete Overlapped ;
DWORD WINAPI CMySvr::WorkerThread(void *lpPara)
{
_stThreadParam_ *pParam =(_stThreadParam_ *)lpPara;
HANDLE CompletionPort=pParam->completePort;
CMySvr *pSvr = pParam->pSvr; DWORD BytesTransferred;
LPOVERLAPPED Overlapped = new OVERLAPPED;
LPPER_HANDLE_DATA PerHandleData;
IO_DATA* data;
DWORD SendBytes, RecvBytes;
DWORD Flags;
while(TRUE)
{
//在这里检查完成端口部分的数据buf区,数据来了吗?
// 这个函数参数要看说明,
// data 就是从管子流出来的数据,
//PerHandleData 也是从管子里取出的,是何时塞进来的,
//就是在建立第2次createIocompletionPort时
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &Overlapped, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
closesocket(PerHandleData->Socket);
ZeroMemory(&data->cltInfo,sizeof(_stCltInfo_));
continue;
}
data=(IO_DATA *)Overlapped;
// 检查数据传送完了吗
if (BytesTransferred == 0)
{
printf("Closing socket %d\n", PerHandleData->Socket);
if (closesocket(PerHandleData->Socket) == SOCKET_ERROR)
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
return 0;
}
printf("传送完了???????????????????????????????????\n");
GlobalFree(PerHandleData); //释放内存块。您必须传给该函数一个内存句柄。
GlobalFree(data);
delete Overlapped;
continue;
}
data=CONTAINING_RECORD(&data->Overlapped,IO_DATA,Overlapped);
if(data->opCode == IO_READ)
{
pSvr->RecvData(data,PerHandleData->Socket);
} data->opCode = IO_READ;
RecvBytes = 0;
Flags = 0;
ZeroMemory(&(data->Overlapped),sizeof(OVERLAPPED));
data->wsabuf.buf = data->Buffer;
data->wsabuf.len = MAX_BUFF_SIZE;
int nRet = WSARecv(
PerHandleData->Socket,
&data->wsabuf, 1, &RecvBytes,
&Flags,
&data->Overlapped, NULL);
if( nRet == SOCKET_ERROR && (ERROR_IO_PENDING != GetLastError()) )
{
cout << "WASRecv Failed::Reason Code::"<< GetLastError() << endl;
closesocket(PerHandleData->Socket);
delete data;
delete Overlapped;
continue;
}
}
return 0;
}