WSA事件模型

服务端骨架:


#include <iostream>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <windows.h>


int main()
{
	WSADATA lpWSAData;
	WSAStartup(MAKEWORD(2, 2), &lpWSAData);

	SOCKADDR_IN saddr{ 0 };
	saddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(9527);

	SOCKET SerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	bind(SerSocket, (PSOCKADDR)&saddr, sizeof(saddr));

	SOCKET arrSocket[WSA_MAXIMUM_WAIT_EVENTS]{ 0 };
	WSAEVENT arrEvent[WSA_MAXIMUM_WAIT_EVENTS]{ 0 };
	WSAEVENT nEvent = WSACreateEvent();
	WSAEventSelect(SerSocket, nEvent, FD_ACCEPT);
	DWORD dwindex = 0;
	arrSocket[dwindex] = SerSocket;
	arrEvent[dwindex] = nEvent;
	dwindex++;

	listen(SerSocket, SOMAXCONN);

	while (true)
	{
		DWORD EventIndex = WSAWaitForMultipleEvents(dwindex, arrEvent, FALSE, WSA_INFINITE, FALSE);
		EventIndex -= WSA_WAIT_EVENT_0;

		WSANETWORKEVENTS NetworkEvents;
		WSAEnumNetworkEvents(arrSocket[EventIndex], arrEvent[EventIndex], &NetworkEvents);

		if (NetworkEvents.lNetworkEvents & FD_ACCEPT)
		{
			if (NetworkEvents.iErrorCode[FD_ACCEPT_BIT] == 0)
			{
				SOCKADDR_IN caddr{ 0 };
				int length = sizeof(caddr);
				SOCKET NewSocket = accept(SerSocket, (PSOCKADDR)&caddr, &length);

				nEvent = WSACreateEvent();
				WSAEventSelect(NewSocket, nEvent, FD_READ|FD_WRITE|FD_CLOSE);
				arrSocket[dwindex] = NewSocket;
				arrEvent[dwindex] = nEvent;
				dwindex++;

				printf("Client IP:%s Prot:%d\r\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
			}
		}
		else if (NetworkEvents.lNetworkEvents & FD_READ)
		{
			if (NetworkEvents.iErrorCode[FD_READ_BIT] == 0)
			{
				char szbuffer[1024]{ 0 };
				recv(arrSocket[EventIndex], szbuffer, sizeof(szbuffer), 0);
				printf("Client Data:%s\r\n", szbuffer);
				std::string str = "收到";
				send(arrSocket[EventIndex], str.c_str(), str.length(), 0);
			}
		}
		else if (NetworkEvents.lNetworkEvents & FD_WRITE)
		{
			if (NetworkEvents.iErrorCode[FD_WRITE_BIT] == 0)
			{
				printf("The client is ready\r\n");
			}
		}
		else if (NetworkEvents.lNetworkEvents & FD_CLOSE)
		{
			for (size_t i = 0; i < dwindex; i++)
			{
				WSACloseEvent(arrEvent[EventIndex]);
				closesocket(arrSocket[EventIndex]);
				dwindex--;
			}
		}
	}
	WSACleanup();
	system("pause");
	return 0;
}

客户端骨架:


#include <iostream>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <windows.h>
#include <process.h>

void RecvData(PVOID pt)
{
	SOCKET sock = *(SOCKET*)pt;
	char szbuffer[1024]{ 0 };
	while (true)
	{
		if (recv(sock, szbuffer, sizeof(szbuffer), 0) == SOCKET_ERROR)
		{
			DWORD dwError = WSAGetLastError();
			if (dwError == WSAETIMEDOUT || dwError == WSAENETDOWN || dwError == WSAECONNRESET)
			{
				closesocket(sock);
				WSACleanup();
				return;
			}
			if (dwError == WSAEWOULDBLOCK)
			{
				Sleep(5);
				continue;
			}
		}
		std::cout << "Server Data:" << szbuffer << std::endl;
	}
}

int main()
{
	WSADATA lpWSAData;
	WSAStartup(MAKEWORD(2, 2), &lpWSAData);

	SOCKADDR_IN caddr{ 0 };
	caddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	caddr.sin_family = AF_INET;
	caddr.sin_port = htons(9527);

	SOCKET CliSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	int iMode = 1;//这行代码将套接字设置为非阻塞模式。这意味着在调用 connect、send 或 recv 等函数时,如果操作不能立即完成,函数不会阻塞,而是立即返回一个错误。
	ioctlsocket(CliSocket, FIONBIO, (u_long*)&iMode);

	connect(CliSocket, (PSOCKADDR)&caddr, sizeof(caddr));

	_beginthread(RecvData, 0, &CliSocket);

	while (true)
	{
		std::cout << "Input:";
		std::string str;
		std::cin >> str;
		send(CliSocket, str.c_str(), str.length(), 0);
		Sleep(20);
	}
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值