WSAEventSelect模型客户端代码示例
程序员文章站
2022-06-16 13:56:15
...
配合WSAEventSelect模型的Server使用,测试效果用。做了些修改,修改为多线程实现IO业务处理。
// g_wsaEventSelect_Client.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <Winsock2.h> #include <malloc.h> #pragma comment(lib,"Ws2_32.lib") SOCKET g_socketServer = INVALID_SOCKET; WSAEVENT g_wsaEvent = WSA_INVALID_EVENT; // 初始化socket void InitSock() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return; } /* Confirm that the WinSock DLL supports 2.2. */ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return; } } void UnInitSock() { if (g_wsaEvent != WSA_INVALID_EVENT) { WSACloseEvent(g_wsaEvent); } if (g_socketServer != INVALID_SOCKET) { closesocket(g_socketServer); } WSACleanup(); } struct ST_THREAD_PARAM { SOCKET socket; WSAEVENT wsaEvent; }; DWORD WINAPI ServiceThread(LPVOID lpThreadParameter) { ST_THREAD_PARAM* pThread = (ST_THREAD_PARAM*)lpThreadParameter; SOCKET socketServer = pThread->socket; WSAEVENT wsaEvent = pThread->wsaEvent; printf("新线程%d起动/n",GetCurrentThreadId()); while(true) { int nRet=::WSAWaitForMultipleEvents(1,&wsaEvent,FALSE,10000,FALSE); if(nRet==WAIT_FAILED) // 失败 { printf("failed WSAWaitForMultipleEvents/n"); break; } else if(nRet==WSA_WAIT_TIMEOUT) // 超时 { printf(" WSA_WAIT_TIMEOUT ... /n"); continue; } else // 成功 -- 网络事件发生 { WSANETWORKEVENTS wsaNetEvent; ::WSAEnumNetworkEvents(socketServer,wsaEvent,&wsaNetEvent); if(wsaNetEvent.lNetworkEvents&FD_READ) { printf("FD_READ event occurs.../n"); char buffer[1024]; int nRet = recv(socketServer,buffer,1024,0); if (nRet>0) { buffer[nRet] = '/0'; printf("收到数据 %s/n",buffer); Sleep(3000); printf("发送数据..../n"); int nSend = send(socketServer,buffer,nRet,0); } else { UnInitSock(); printf("线程%d退出/n",GetCurrentThreadId()); return -1; } } else if(wsaNetEvent.lNetworkEvents&FD_WRITE) { printf("FD_WRITE event occurs.../n"); printf("发送数据..../n"); char szBuffer[] = "Hello world..."; int nLen = sizeof(szBuffer); nRet = send(socketServer,szBuffer,nLen,0); if (nRet == SOCKET_ERROR) { printf("send() error .../n"); UnInitSock(); printf("线程%d退出/n",GetCurrentThreadId()); return -1; } printf("nRet of send() is %d/n",nRet); } if(wsaNetEvent.lNetworkEvents&FD_CLOSE) { printf("FD_CLOSE event occurs.../n"); int nErrorCode = WSAGetLastError(); printf("Error code is %d/n",nErrorCode); if (nErrorCode == WSAECONNRESET) { printf("WSAECONNRESET error./n"); } else if (nErrorCode == WSAENETDOWN) { printf("WSAENETDOWN error./n"); } else if (nErrorCode == WSAENETRESET) { printf("WSAENETRESET error./n"); } UnInitSock(); printf("线程%d退出/n",GetCurrentThreadId()); return -1; } } } printf("线程%d退出/n",GetCurrentThreadId()); return 0; } int _tmain(int argc, _TCHAR* argv[]) { InitSock(); g_socketServer=socket(AF_INET,SOCK_STREAM,0); if (g_socketServer == INVALID_SOCKET) { UnInitSock(); return -1; } sockaddr_in sin; sin.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); sin.sin_family=AF_INET; sin.sin_port=htons(3456); if (connect(g_socketServer,(sockaddr*)&sin,sizeof(sockaddr)) == SOCKET_ERROR) { UnInitSock(); return -1; } g_wsaEvent=::WSACreateEvent(); ::WSAEventSelect(g_socketServer,g_wsaEvent,FD_READ|FD_WRITE|FD_CLOSE); ST_THREAD_PARAM* pThreadParam = new ST_THREAD_PARAM(); pThreadParam->socket = g_socketServer; pThreadParam->wsaEvent = g_wsaEvent; HANDLE hThread = ::CreateThread(NULL,0,ServiceThread,(LPVOID)pThreadParam,0,NULL); if (hThread == INVALID_HANDLE_VALUE) { printf("Failed to create new thread.../n"); UnInitSock(); return -1; } printf("WaitForSingleObject(hThread,INFINITE) waiting.../n"); WaitForSingleObject(hThread,INFINITE); printf("WaitForSingleObject(hThread,INFINITE) return .../n"); delete pThreadParam; //while(true) //{ // int nRet=::WSAWaitForMultipleEvents(1,&g_wsaEvent,FALSE,10000,FALSE); // if(nRet==WAIT_FAILED) // 失败 // { // printf("failed wait for single object/n"); // break; // } // else if(nRet==WSA_WAIT_TIMEOUT) // 超时 // { // printf(" WSA_WAIT_TIMEOUT ... /n"); // continue; // } // else // 成功 -- 网络事件发生 // { // WSANETWORKEVENTS wsaNetEvent; // ::WSAEnumNetworkEvents(g_socketServer,g_wsaEvent,&wsaNetEvent); // if(wsaNetEvent.lNetworkEvents&FD_READ) // { // printf("FD_READ event occurs.../n"); // char buffer[1024]; // int nRet = recv(g_socketServer,buffer,1024,0); // if (nRet>0) // { // buffer[nRet] = '/0'; // printf("收到数据 %s/n",buffer); // Sleep(3000); // printf("发送数据..../n"); // int nSend = send(g_socketServer,buffer,nRet,0); // } // else // { // UnInitSock(); // return -1; // } // // } // else if(wsaNetEvent.lNetworkEvents&FD_WRITE) // { // printf("FD_WRITE event occurs.../n"); // printf("发送数据..../n"); // char szBuffer[] = "Hello world..."; // int nLen = sizeof(szBuffer); // nRet = send(g_socketServer,szBuffer,nLen,0); // if (nRet == SOCKET_ERROR) // { // printf("send() error .../n"); // UnInitSock(); // return -1; // } // printf("nRet of send() is %d/n",nRet); // } // if(wsaNetEvent.lNetworkEvents&FD_CLOSE) // { // printf("FD_CLOSE event occurs.../n"); // int nErrorCode = WSAGetLastError(); // printf("Error code is %d/n",nErrorCode); // if (nErrorCode == WSAECONNRESET) // { // printf("WSAECONNRESET error./n"); // } // else if (nErrorCode == WSAENETDOWN) // { // printf("WSAENETDOWN error./n"); // } // else if (nErrorCode == WSAENETRESET) // { // printf("WSAENETRESET error./n"); // } // UnInitSock(); // return -1; // } // } //} return 0; } /* * Windows Sockets definitions of regular Berkeley error constants #define WSAEWOULDBLOCK (WSABASEERR+35) #define WSAEINPROGRESS (WSABASEERR+36) #define WSAEALREADY (WSABASEERR+37) #define WSAENOTSOCK (WSABASEERR+38) #define WSAEDESTADDRREQ (WSABASEERR+39) #define WSAEMSGSIZE (WSABASEERR+40) #define WSAEPROTOTYPE (WSABASEERR+41) #define WSAENOPROTOOPT (WSABASEERR+42) #define WSAEPROTONOSUPPORT (WSABASEERR+43) #define WSAESOCKTNOSUPPORT (WSABASEERR+44) #define WSAEOPNOTSUPP (WSABASEERR+45) #define WSAEPFNOSUPPORT (WSABASEERR+46) #define WSAEAFNOSUPPORT (WSABASEERR+47) #define WSAEADDRINUSE (WSABASEERR+48) #define WSAEADDRNOTAVAIL (WSABASEERR+49) #define WSAENETDOWN (WSABASEERR+50) #define WSAENETUNREACH (WSABASEERR+51) #define WSAENETRESET (WSABASEERR+52) #define WSAECONNABORTED (WSABASEERR+53) #define WSAECONNRESET (WSABASEERR+54) #define WSAENOBUFS (WSABASEERR+55) #define WSAEISCONN (WSABASEERR+56) #define WSAENOTCONN (WSABASEERR+57) #define WSAESHUTDOWN (WSABASEERR+58) #define WSAETOOMANYREFS (WSABASEERR+59) #define WSAETIMEDOUT (WSABASEERR+60) #define WSAECONNREFUSED (WSABASEERR+61) #define WSAELOOP (WSABASEERR+62) #define WSAENAMETOOLONG (WSABASEERR+63) #define WSAEHOSTDOWN (WSABASEERR+64) #define WSAEHOSTUNREACH (WSABASEERR+65) #define WSAENOTEMPTY (WSABASEERR+66) #define WSAEPROCLIM (WSABASEERR+67) #define WSAEUSERS (WSABASEERR+68) #define WSAEDQUOT (WSABASEERR+69) #define WSAESTALE (WSABASEERR+70) #define WSAEREMOTE (WSABASEERR+71) */