Getlasterror 997,重叠 io进行中C/C++ code问题:服务端采用重叠io模型,客户端发送数据给服务器。我遇到一个
Getlasterror 997,重叠 io进行中
- C/C++ code
问题:服务端采用重叠io模型,客户端发送数据给服务器。我遇到一个问题:客户端发送数据给服务端,结果服务端没有收到,而且还出现了逻辑不通的情况。else if(nRet!=WSA_IO_PENDING) //WSA_IO_PENDING就是997 { printf("WSARecv failed with error code: %d/n", WSAGetLastError()); closesocket(g_ol[nPos]->sock); g_ol[nPos]=g_ol[g_nIndex-1]; g_nIndex--; nPos--; continue; }GetLastError的结果是997!!!这段代码的逻辑是:如果不等于997,那么则进入这块代码, 既然进入了额,那么为什么Getlasterror的返回值又是997呢?这个确实。。。。。。/*服务端程序:开启线程接受连将,接受数据,就这么个功能!!!*/#include"stdafx.h"#include <Winsock2.h>#include <Windows.h>#include <process.h>#pragma comment(lib, "WS2_32.lib")#define MAX_BUFFER 256#define MAX_TIMEOUT 4000//初始化环境,卸载环境的一个类class CInitSock {public: CInitSock(BYTE minorVer = 2, BYTE majorVer = 2) { // 初始化WS2_32.dll WSADATA wsaData; WORD sockVersion = MAKEWORD(minorVer, majorVer); if(::WSAStartup(sockVersion, &wsaData) != 0) { exit(0); } } ~CInitSock() { ::WSACleanup(); }};//封装了重叠结构(含事件),套接字,缓冲区typedef struct _OVERLAPPED_INFO_{ public: _OVERLAPPED_INFO_() { Clean(); } ~_OVERLAPPED_INFO_() { Clean(); } _OVERLAPPED_INFO_& operator=(_OVERLAPPED_INFO_ const& another) { ol.hEvent = another.ol.hEvent; sock = another.sock; memset(szBuf,0,sizeof(MAX_BUFFER)); strcpy(szBuf,another.szBuf); return *this; }protected: void Clean() { ol.hEvent = NULL; sock = INVALID_SOCKET; wsaBuf.buf = szBuf; wsaBuf.len = MAX_BUFFER; memset(szBuf, 0, sizeof(szBuf)); }public: WSAOVERLAPPED ol; SOCKET sock; WSABUF wsaBuf; char szBuf[MAX_BUFFER];}OVERLAPPEDINFO, *POVERLAPPEDINFO;WSAEVENT g_event[WSA_MAXIMUM_WAIT_EVENTS] = {0}; //事件对象 组OVERLAPPEDINFO* g_ol[WSA_MAXIMUM_WAIT_EVENTS] = {0}; //重叠io结构体数组指针int g_nIndex = 0; //客户端个数BOOL g_bExitThread = FALSE; //退出标志unsigned __stdcall ThreadProc(LPVOID lParam); //功能:接受连接,接受数据CInitSock g_InitSock;SOCKET g_sListen ; //监听套接字#include <stdio.h>#include <process.h>int main(){// 创建套接字 g_sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(INVALID_SOCKET == g_sListen) { printf("socket failed with error code: %d/n", WSAGetLastError()); return EXIT_FAILURE; } SOCKADDR_IN addr = {0}; addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addr.sin_family = AF_INET; addr.sin_port = htons(5050); if(SOCKET_ERROR == bind(g_sListen, (LPSOCKADDR)&addr, sizeof(addr))) //帮顶 { printf("bind failed with error code: %d/n", WSAGetLastError()); closesocket(g_sListen); return EXIT_FAILURE; } if(SOCKET_ERROR == listen(g_sListen, 5)) //监听 { printf("listen failed with error code: %d/n", WSAGetLastError()); closesocket(g_sListen); return EXIT_FAILURE; } //g_ol[g_nIndex] = new OVERLAPPEDINFO; //g_ol[g_nIndex]->sock = g_sListen; //g_event[g_nIndex] = g_ol[g_nIndex]->ol.hEvent = WSACreateEvent(); //g_nIndex++; u_long argp=1; ioctlsocket(g_sListen,FIONBIO,&argp); // 讲监听套接字设置为非堵塞 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, NULL); if(NULL == hThread) { printf("_beginthreadex failed with error code: %d/n", GetLastError()); closesocket(g_sListen); return EXIT_FAILURE; } printf("Server start listen and wait for client to connect .../n"); WaitForSingleObject(hThread, INFINITE); g_bExitThread = TRUE; // Exit thread. CloseHandle(hThread); return 0;}//线程功能:接受连接,接受数据unsigned __stdcall ThreadProc(LPVOID lParam){ while(!g_bExitThread) { DWORD dwFlags, dwTrans, BytesTransferred; int nRet; dwFlags=0; SOCKADDR_IN remote = {0}; int len = sizeof(remote); SOCKET sNew=accept(g_sListen,(LPSOCKADDR)&remote,&len); if(INVALID_SOCKET !=sNew) { g_ol[g_nIndex]=new OVERLAPPEDINFO; g_ol[g_nIndex]->sock=sNew; g_event[g_nIndex]=g_ol[g_nIndex]->ol.hEvent=WSACreateEvent(); g_nIndex++; } for(int nPos=0; nPos<g_nIndex; nPos++) { nRet= WSARecv(g_ol[nPos]->sock, &(g_ol[nPos]->wsaBuf), 1, &dwTrans, &dwFlags, &(g_ol[nPos]->ol), NULL); if(nRet==0) //成功 { printf("收到的数据为:%s\n",g_ol[nPos]->szBuf); continue; } else if(nRet!=WSA_IO_PENDING) { printf("WSARecv failed with error code: %d/n", WSAGetLastError()); closesocket(g_ol[nPos]->sock); g_ol[nPos]=g_ol[g_nIndex-1]; g_nIndex--; nPos--; continue; } //等待事件对象触发 nRet = WSAWaitForMultipleEvents(1, &g_event[g_nIndex], TRUE, MAX_TIMEOUT, FALSE); if(WSA_WAIT_FAILED == nRet) //发生错误! { // 记录日志 continue; } if(nRet==WSA_WAIT_TIMEOUT) //超时后,如何处理 { continue; //仅仅continue,可以不? } if( WSAGetOverlappedResult(g_ol[nPos]->sock,&(g_ol[nPos]->ol), &BytesTransferred, FALSE, &dwFlags) ) { printf("收到的数据为:%s\n",g_ol[nPos]->szBuf); } else { } } //end for } //end while printf("Server to exit ... /n"); return 0;}
以上重点是线程函数!!1
客户端关键代码:
for(int i=0; i<4000;i++)
{
Sleep(200);
send(s,buf,100,0);
}
[解决办法]
WSARecv的返回值永远也不会等于ERROR_IO_PENDING啊,所以
你那个if是必然进去的!
