【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 编辑 ]