|
楼主 |
发表于 2008-9-21 15:18:27
|
显示全部楼层
是这样的,其实,我自己的服务器也紧紧是一个转发的机能
并没有其他的功能
是使用完成端口做的
问题是,现在的其他公司做的接口在发送数据的时候,其TCP的数据没有明确的定义数据头相关信息
而且,在使用完成端口中,我不知道该怎么样进行循环接收数据
我按照标准的完成端口机制,在工作线程中使用GetQueuedCompletionStatus,得到缓冲区的字节数
然后读取,并根据重叠数据的结构,进行相关处理,发送下一个wsarecv
工作线程的代码如下
DWORD WINAPI WorkThread(LPVOID lpParam)
{
DWORD BytesTransferred;
CClientContext* pPerHandleData = NULL;
LPPER_IO_OPERATION_DATA pPerIoData = NULL;
int nResult;
while(TRUE)
{
if (GetQueuedCompletionStatus(g_hIOCompletionPort, &BytesTransferred,
(LPDWORD)&pPerHandleData, (LPOVERLAPPED *) &pPerIoData, INFINITE) == 0)
{
char strErr[256];
wsprintf(strErr, "GetQueuedCompletionStatus failed with error %d",GetLastError());
WriteDebugInfo(strErr);
RemoveFromClientListAndFreeMemory(pPerHandleData);
GlobalFree(pPerIoData);
return 0;
}
// First check to see if an error has occured on the socket and if so
// then close the socket and cleanup the SOCKET_INFORMATION structure
// associated with the socket.
if (BytesTransferred == 0)
{
if (closesocket(pPerHandleData->GetSocket()) == SOCKET_ERROR)
{
char strErr[256];
wsprintf(strErr, "closesocket() failed with error %d",WSAGetLastError());
WriteDebugInfo(strErr);
RemoveFromClientListAndFreeMemory(pPerHandleData);
GlobalFree(pPerIoData);
return 0;
}
RemoveFromClientListAndFreeMemory(pPerHandleData);
GlobalFree(pPerIoData);
continue;
}
switch(pPerIoData->oper)
{
case SVR_IO_WRITE:
ZeroMemory(pPerIoData,sizeof(PER_IO_OPERATION_DATA));
pPerIoData->Overlapped.hEvent = NULL;
pPerIoData->Overlapped.Internal = 0;
pPerIoData->Overlapped.InternalHigh = 0;
pPerIoData->Overlapped.Offset = 0;
pPerIoData->Overlapped.OffsetHigh = 0;
pPerIoData->DataBuf.buf = (char*)&(pPerIoData->Buffer);
pPerIoData->DataBuf.len = DATA_BUFSIZE;
pPerIoData->oper = SVR_IO_READ;
pPerIoData->flags = 0;
char strTmpB[DATA_BUFSIZE];
wsprintf(strTmpB,"before recv+++++++++++++%s",pPerIoData->Buffer);
WriteDebugInfo(strTmpB,1);
nResult = WSARecv(pPerHandleData->GetSocket(), &(pPerIoData->DataBuf),1,NULL,&(pPerIoData->flags),&(pPerIoData->Overlapped),NULL);
char strTmp[DATA_BUFSIZE];
wsprintf(strTmp,"after recv______________%s",pPerIoData->Buffer);
WriteDebugInfo(strTmp,1);
if((nResult == SOCKET_ERROR) && (WSAGetLastError() != ERROR_IO_PENDING))
{
WriteDebugInfo("WSARecv Error\n");
RemoveFromClientListAndFreeMemory(pPerHandleData);
GlobalFree(pPerIoData);
}
break;
case SVR_IO_READ:
{
pPerIoData->DataBuf.len = BytesTransferred;
pPerIoData->oper = SVR_IO_WRITE;
pPerIoData->flags = 0;
if((nResult == SOCKET_ERROR) &&
(WSAGetLastError() != ERROR_IO_PENDING))
{
WriteDebugInfo("WSASend ERROR\n");
RemoveFromClientListAndFreeMemory(pPerHandleData);
GlobalFree(pPerIoData);
}
char strTmp[DATA_BUFSIZE];
wsprintf(strTmp,"___________________________%s\n\n\n",pPerIoData->DataBuf.buf);
// WriteDebugInfo(pPerIoData->DataBuf.buf);
WriteDebugInfo(strTmp);
//................
// char ss[] = "123456789";
// send(pPerHandleData->GetSocket(),ss,sizeof(ss),0);
SendNextRequest( pPerIoData, pPerHandleData);
}
break;
default:
break;
}
}
return 1;
}
void SendNextRequest(LPPER_IO_OPERATION_DATA lpPerIOData, CClientContext* pClientContext)
{
ZeroMemory(lpPerIOData,sizeof(PER_IO_OPERATION_DATA));
lpPerIOData->Overlapped.hEvent = NULL;
lpPerIOData->Overlapped.Internal = 0;
lpPerIOData->Overlapped.InternalHigh = 0;
lpPerIOData->Overlapped.Offset = 0;
lpPerIOData->Overlapped.OffsetHigh = 0;
lpPerIOData->DataBuf.buf = (char*)&(lpPerIOData->Buffer);
lpPerIOData->DataBuf.len = DATA_BUFSIZE;
lpPerIOData->oper = SVR_IO_READ;
lpPerIOData->flags = 0;
int nResult = WSARecv(pClientContext->GetSocket(),&(lpPerIOData->DataBuf),1,NULL,
&(lpPerIOData->flags),&(lpPerIOData->Overlapped),NULL);
if((nResult == SOCKET_ERROR) && (WSAGetLastError() != ERROR_IO_PENDING))
{
WriteDebugInfo("WSARecv Error in SendNextRequest",1);
RemoveFromClientListAndFreeMemory(pClientContext);
GlobalFree(lpPerIOData);
}
// WriteDebugInfo("&&&&&&&&&&&&&&&&&&&&&&&&&");
// char strTmp[DATA_BUFSIZE];
// wsprintf(strTmp,"!!!!!!!!!!!!!!!!!!!!!!!!%s",lpPerIOData->DataBuf.buf);
// WriteDebugInfo(strTmp,1);
}
劳驾了,棒忙看看吧 |
|