`
alienchang
  • 浏览: 31596 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

WSAEventSelect模型客户端代码示例

阅读更多
配合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)
*/
分享到:
评论

相关推荐

    WSAEventSelect客户端

    最后,`WSAEventClient`这个名字暗示了这个项目是一个使用`WSAEventSelect`的客户端示例。这个客户端可能包括连接服务器、发送请求、接收响应、断开连接等基本功能。通过分析和学习这个项目的源代码,我们可以更深入...

    VC网络编程模型示例 - WSAEventSelect

    **VC网络编程模型示例 - WSAEventSelect** 在Windows Socket API (Winsock)中,`WSAEventSelect`是一个重要的函数,它允许程序通过事件对象(如Windows事件或I/O完成端口)来处理网络事件。这个模型在Visual C++...

    WSAEventSelect

    在压缩包文件"WSAEventSelect"中,可能包含了服务器端和客户端的源代码,它们演示了如何在VC++ 6.0环境中使用`WSAEventSelect`进行异步通信。通过学习和分析这些代码,开发者可以更好地理解`WSAEventSelect`的使用...

    Windows Socket五种I/O模型——代码全攻略

    本文将详细介绍Windows Socket支持的五种I/O模型,并提供相应的代码示例。 #### 一、阻塞I/O模型 阻塞I/O是最常见的I/O模型,其特点是当调用I/O操作时,如果操作未能立即完成,则调用线程会被阻塞,直到I/O操作...

    WSAEventSelect服务器端

    文件名为“WSAEventServer”的压缩包,很可能是这个示例程序的源代码文件,包含了实现上述功能的C++代码。解压后,我们可以看到服务器如何初始化、监听、接受连接、处理事件并关闭连接的具体实现。 总结来说,...

    WSAEventSelet模型

    在提供的压缩包文件"EventMode"中,很可能包含了一个示例代码或文档,详细展示了如何在服务器端使用WSAEventSelect模型。这个文件可以作为学习和理解WSAEventSelect实际应用的一个良好起点,通过阅读和运行其中的...

    windowsSocket-WSAEventSelect.rar_WSAEventSelect_windows WSAEVENT

    在Windows平台上进行网络编程时,WSAEventSelect是Windows Socket...这个压缩包中的示例展示了如何将WSAEventSelect应用于实际项目——一个网络五子棋游戏中,这为我们提供了一个学习和实践网络编程的实用案例。

    幽默Socket+IO模型.doc幽默Socket+IO模型.doc

    - **WSAEventSelect模型**:类似于`WSAAsyncSelect`,但使用的是事件对象而不是窗口消息,提供了一种更灵活的事件通知机制。 - **Overlapped I/O模型**:这是一种真正的异步I/O模型,在Windows上特别高效。通过...

    IOCP的socket通讯程序示例代码

    在本文中,我们将深入探讨如何使用IOCP(I/O...在阅读和分析示例代码时,重点关注如何创建和管理IOCP,如何设置Socket为异步模式,以及如何处理I/O完成事件,这将有助于我们更好地理解和掌握IOCP在Socket通信中的应用。

    Socket IO模型之选择

    下面是一个简单的客户端代码示例,该程序使用 `select` 函数来实现客户端与服务器之间的通信: ```cpp #include "stdafx.h" #include #include #pragma comment(lib, "ws2_32.lib") #define SERVER_ADDRESS "192....

    SOCKET IO 模型

    在上面的代码示例中,`FD_ACCEPT`, `FD_READ`, `FD_WRITE` 和 `FD_CLOSE` 是常见的四种事件类型,分别对应于新的连接请求、数据可读、数据可写和连接关闭。当这些事件发生时,Windows会发送一个自定义的消息(如`WM_...

    有关Socket模型详解

    最后,让我们回顾一下客户端示例代码。它展示了如何创建Socket,连接到服务器,以及发送和接收数据。客户端使用阻塞模式进行I/O操作,这在单线程应用中是常见的做法。然而,对于服务器端,由于可能需要同时处理多个...

    1_WINSOCK的I/O模型_

    在压缩包文件中,"shiyan5kehu"可能是客户端的源代码示例,而"shiyan5fuwu"可能是服务器端的源代码示例。分析这些源代码,我们可以更深入地理解WINSOCK的I/O模型是如何在实际项目中被使用的。 总之,理解和掌握...

    Socket模型c++版本详解

    下面通过一个简单的客户端代码示例来进一步理解Socket的基本使用方法: ```cpp #include #include #define SERVER_ADDRESS "137.117.2.148" #define PORT 5150 #define MSG_SIZE 1024 #pragma comment(lib, "ws2...

    5种winsock_IO模型

    本文将详细介绍这些模型,并通过一个简单的响应式服务器示例来阐述每种模型的特点及应用场景。 #### 二、选择模型(Select) 选择模型是最常见的I/O模型之一,它利用`select`函数来实现对I/O的管理。这一模型最初是...

    indows操作的socket操作总结

    在上述代码示例中,客户端简单地创建套接字、连接服务器并进行连续的发送和接收操作。要实现上述五种I/O模型,服务器端需要采用不同的策略来处理来自多个客户端的连接请求。例如,使用Select模型,服务器会在一个...

    WINSOCK IO模型.pdf

    ### WINSOCK IO模型概述 本文旨在深入探讨Windows环境下针对套接字的多种输入/...而对于简单的客户端应用,`select`模型可能就足够了。理解这些模型的工作原理和技术细节可以帮助开发者更好地设计和优化网络应用程序。

    精通Windows Sockets网络开发:基于Visual C++实现-带源码

    精通Windows Sockets网络开发——基于Visual C++实现 目 录 第1篇网络开发基础篇 第1章准备开发环境 1.1windows sockets开发概述 ...第8章wsaeventselect模型开发 第9章重叠i/o模型开发 第10章完成端口模型开发

    Windows套接字IO模型.pdf

    **示例代码**: ```cpp #include #include int main() { SOCKET sServer, sClient; FD_SET readfds; struct sockaddr_in addrServer, addrClient; int nSize, nRet; // 初始化Winsock库 WSAStartup...

    IOCP多线程socket模型

    IOCP(I/O Completion Port,I/O完成端口)是...`iocp_server`和`iocp_client`示例代码提供了理解和实践这一模型的宝贵资源。通过深入学习和理解这个模型,开发者可以在Windows平台上构建出更加健壮、高效的网络服务。

Global site tag (gtag.js) - Google Analytics