【IOCP】客户端连接后服务端没反映【四十分!!【可另开贴给分】!!求解决!!!!!!!!!!!!!】
困扰很长时间的一个问题。。一直没有解决。。就是。。服务端能监听端口, 也能与客户端建立连接。。 但是。客户端连接后。。怎么都没有反应。。。我在ServerThreadFunc中的switch这句下一个断点。。断点只会在创建线程的时候被触发。。也不知道我说明白了没有。。
大体说就是:
服务端监听端口后。。客户端能连接。。但是服务端没有反应。。求解决。。
服务端代码- ServerThreadFunc
程序代码:unsigned __stdcall ServerThreadFunc(void* pArguments)
{
DWORD dwRecv = 0,
dwSend=0,
dwTransCount = 0,
dwFlags=0;
PPER_IO_DATA pPerIoData = NULL;
PPER_HANDLE_DATA pPerHandleData = NULL;
while (TRUE)
{
if (GetQueuedCompletionStatus(hIOCP, &dwTransCount, (LPDWORD)&pPerHandleData,
(LPOVERLAPPED*)&pPerIoData, INFINITE))
{
if (0 == dwTransCount&&IO_QUIT == pPerIoData->TYPE)
{
EnterCriticalSection(&csLinkList);
//从链表中删除
LeaveCriticalSection(&csLinkList);
closesocket(pPerHandleData->Socket);
//continue;
}
switch (pPerIoData->TYPE)
{
case IO_SIGN:
pPerHandleData->Socket = pPerIoData->socket;
setsockopt(pPerIoData->socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
(char*)&(pPerHandleData->Socket), sizeof(pPerHandleData->Socket));
//将新的客户套接字与完成端口连接
CreateIoCompletionPort((HANDLE)pPerHandleData->Socket,
hIOCP, (ULONG_PTR)pPerHandleData, 0);
memset(&(pPerIoData->OverLapped), 0, sizeof(OVERLAPPED));
pPerIoData->TYPE = IO_RECV; //将状态设置成接收
//设置WSABUF结构
pPerIoData->DataBuf.buf = pPerIoData->Buf;
pPerIoData->DataBuf.len = 8192;
dwFlags = 0;
WSARecv(pPerHandleData->Socket, &pPerIoData->DataBuf, 1, &dwRecv, &dwFlags, (LPWSAOVERLAPPED)(pPerIoData), NULL);
m_TabForm001.AddClient(_T("guid"), _T("ipp"));
break;
case IO_RECV:
memset(&(pPerIoData->OverLapped), 0, sizeof(OVERLAPPED));
pPerIoData->TYPE = IO_SEND; //将状态设置成发送
WSASend(pPerHandleData->Socket, &pPerIoData->DataBuf,
1, &dwSend, 0, &(pPerIoData->OverLapped), NULL);
m_TabForm001.AddClient(_T("guid"), _T("i4174171pp"));
break;
case IO_SEND:
m_TabForm001.AddClient(_T("guid"), _T("41414141414141414141171pp"));
break;
case IO_QUIT:
break;
default:
break;
}
}
}
return TRUE;
}服务端代码-初始化
程序代码:int CIOCP::Init(int port)
{
WSADATA wsa;
memset(&wsa,0,sizeof(WSADATA));
WSAStartup(MAKEWORD(2,2),&wsa);
listenSocket = INVALID_SOCKET;
listenSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP,0, 0, WSA_FLAG_OVERLAPPED);
if (listenSocket == INVALID_SOCKET)
{
WSACleanup();
return FALSE;
}
SOCKADDR_IN localAddr;
memset(&localAddr,0,sizeof(SOCKADDR_IN));
localAddr.sin_family = AF_INET;
localAddr.sin_addr.S_un.S_addr = INADDR_ANY;
localAddr.sin_port = htons(4262);
if (bind(listenSocket, (SOCKADDR*)&localAddr, sizeof(SOCKADDR)))
{
closesocket(listenSocket);
WSACleanup();
return FALSE;
}
if (listen(listenSocket, SOMAXCONN) != 0)
{
GetLastError();
closesocket(listenSocket);
WSACleanup();
return FALSE;
}
hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if (hIOCP == NULL)
{
return FALSE;
}
LPFN_ACCEPTEX lpfnAcceptEx = NULL;
GUID guidAcceptEx = WSAID_ACCEPTEX;
DWORD dwBytes = 0;
WSAIoctl(listenSocket, SIO_GET_EXTENSION_FUNCTION_POINTER,
&guidAcceptEx, sizeof(guidAcceptEx), &lpfnAcceptEx, sizeof(lpfnAcceptEx),
&dwBytes, NULL, NULL);
SYSTEM_INFO si;
GetSystemInfo(&si);
//启动线程
for (int i = 0; i < (si.dwNumberOfProcessors * 2 + 2); i++)
{
_beginthreadex(NULL,
0,
&ServerThreadFunc,
NULL,
0,
0);
}
//投递 CUP*2+2个请求
for (int i = 0; i < (si.dwNumberOfProcessors * 2 + 2); i++)
{
PPER_IO_DATA perIoData = new PER_IO_DATA;
memset(&(perIoData->OverLapped), 0, sizeof(OVERLAPPED));
perIoData->TYPE = IO_SIGN;
//在使用AcceptEx前需要事先重建一个套接字用于其第二个参数。这样目的是节省时间
//通常可以创建一个套接字库
perIoData->socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED);
DWORD flags = 0;
lpfnAcceptEx(listenSocket, perIoData->socket, perIoData->DataBuf.buf,
perIoData->DataBuf.len - ((sizeof(SOCKADDR_IN)+16) * 2),
sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, &dwBytes,
&(perIoData->OverLapped));
}
return TRUE;
}客户端代码:
程序代码:
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
return FALSE;
}
if (LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1) {
WSACleanup();
return FALSE;
}
while (true)
{
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(4262);
connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
while (1)
{
printf(".");
send(sockClient, "This is lisi", strlen("This is lisi") + 1, 0);
}
char recvBuf[100];
recv(sockClient, recvBuf, 100, 0);
printf("%s\n", recvBuf);
closesocket(sockClient);
}
WSACleanup();
[ 本帖最后由 zxk112 于 2015-2-14 16:58 编辑 ]




