欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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)
*/