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

最简单的WSAEventSelect模型(注意注释的地方)

程序员文章站 2022-03-02 15:30:49
...
// Win32SocketTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "winsock2.h"
//#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"Ws2_32.lib")
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
	int arg = 1000;
	int theOp = ~arg + 1;
	int theOp2 = ~theOp + 1;
	//启动socket
	WSADATA data;
	WSAStartup(MAKEWORD(2,2),&data);
	//设置服务器地址
	SOCKADDR_IN addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(5000);
	addr.sin_addr.S_un.S_un_b.s_b1 = 113;
	addr.sin_addr.S_un.S_un_b.s_b2 = 90;
	addr.sin_addr.S_un.S_un_b.s_b3 = 50;
	addr.sin_addr.S_un.S_un_b.s_b4 = 170;
	int len = sizeof(addr);

	//创建socket
	SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

	//绑定socket
	bind(s,(sockaddr*)&addr,sizeof(addr));
	while(true)
	{
		//监听socket
		listen(s,SOMAXCONN);

		//创建与socket关联的事件
		WSAEVENT event = WSACreateEvent();
		WSAEventSelect(s,event,FD_ACCEPT | FD_CLOSE);

		//等待事件发生
		//////////////////////////////////////////////////////////////////////////
		//阻塞!必须建立线程去处理。。以后改进。
		DWORD nResult = WaitForSingleObject(event, INFINITE);
		if (nResult == WAIT_OBJECT_0)
		{
			//查询是什么事件发生了。
			WSANETWORKEVENTS ne;
			WSAEnumNetworkEvents(s,event,&ne);
			if (ne.lNetworkEvents&FD_ACCEPT)
			{
				//为这个客户端建立一个套接字用来收发数据。
				SOCKADDR_IN clientAddr;
				int addrlen = sizeof(clientAddr);
				SOCKET sClient = accept(s, (sockaddr*)&clientAddr, &addrlen);

				//////////////////////////////////////////////////////////////////////////
				/////阻塞!必须建立线程去处理。。以后改进。	
				WSAEVENT eventWriteRead = WSACreateEvent();
				WSAEventSelect(sClient,eventWriteRead,FD_WRITE|FD_READ|FD_CLOSE);
				while (true)
				{
					WaitForSingleObject(eventWriteRead,INFINITE);
					{
						//查询是什么事件发生了。
						WSANETWORKEVENTS ne;
						WSAEnumNetworkEvents(sClient,eventWriteRead,&ne);
						if (ne.lNetworkEvents&FD_WRITE)
						{
							char a[1000];
							memset(a,0,sizeof(a));
							std::cin>>a;
							send(sClient, a, sizeof(a),0);
						}
						else if (ne.lNetworkEvents&FD_READ)
						{
							char buf[1000];
							buf[999] = 0;
							recv( sClient,buf,len,0);
							std::cout<<buf;
						}
						else if (ne.lNetworkEvents&FD_CLOSE)
						{
							closesocket(s);
						}
					}
					WSAResetEvent(eventWriteRead);
				}
				//////////////////////////////////////////////////////////////////////////
				
			}
			else
			{
				closesocket(s);
			}
		} 
		//////////////////////////////////////////////////////////////////////////
		WSAResetEvent(event);
		
	}
	return 0;
}

 要改进的地方

1。阻塞的地方waiforsingle改为waitformultiple,并且用线程去处理。

2。用短连接代替长连接来处理。收到一个完整的业务包之后,进行关闭。

相关标签: Socket