计算机网路之服务端2.0

计算机网路之服务端2.0是建立在1.0的基础上,建立了一个监听队列,实现一个服务端同时监听多个客户端,下面是2.0的模型

 

代码实现如下:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#include <winsock2.h>
#pragma comment(lib,"ws2_32")
int main()
{
	// 初始化win网络版本库
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);


	// 1.创建协议(服务端句柄)
	// AF_INET: IPV4 192.168.1.1   00::bb::::11
	// SOCK_STREAM: 流式协议
	// IPPROTO_TCP:TCP
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (INVALID_SOCKET == sock)
	{
		printf("socket create fail! %d\n", GetLastError());
		return 0;
	}
	printf("1. socket create success\n");

	// 2.绑定IP端口

	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	// 0.0.0.0  绑定所有IP
	// 

	addr.sin_addr.s_addr = inet_addr("0.0.0.0");
	addr.sin_port = htons(7890);
	if (SOCKET_ERROR == bind(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)))
	{
		printf("socket bind fail! %d\n", GetLastError());
		return 0;

	}
	printf("2. socket bind success  0.0.0.0:%d\n", 7890);

	// 3.监听端口
	// 开门营业
	listen(sock, 5);
	printf("3. socket listen success\n");
	SOCKET socks[1024] = { 0 };
	int index = 0;
	while (1)
	{

		FD_SET reads;
		FD_ZERO(&reads);


		FD_SET(sock, &reads);

		for (int i = 0; i < index; ++i)
		{
			FD_SET(socks[i], &reads);
		}


		// 0超时  -1 socket错误  >0 相应的客户端数据
		int nSetlect = select(NULL, &reads, NULL, NULL, NULL);

		// 检测服务端句柄是否有响应
		if (FD_ISSET(sock, &reads))
		{
			// 4.等待用户连接
			struct sockaddr_in clientAddr;
			int clientLen = sizeof(clientAddr);
			SOCKET clientSock = accept(sock, (struct sockaddr*)&clientAddr, &clientLen);
			if (INVALID_SOCKET == clientSock)
			{
				printf("socket accept fail! %d\n", GetLastError());
				return 0;
			}
			printf("4. socket accept success [%s][%d]\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));
			socks[index++] = clientSock;
		}

		for (int i = 0; i < index; ++i)
		{
			SOCKET clientSock = socks[i];
			if (FD_ISSET(clientSock, &reads))
			{

				// 5.接受数据
				char buff[1024] = { 0 };
				int recvLen = recv(clientSock, buff, 1024, 0);
				printf("recv[%4d]:%s", recvLen, buff);
				// TODO recvlen <=0 close
				if (recvLen <= 0)
				{
					closesocket(clientSock);
					// TODO 移除客户端句柄
					socks[i] = socks[index - 1];
					--index;
					--i;
					continue;
				}
				// 6.发送数据
				int sendLen = send(clientSock, buff, recvLen, 0);
				// sendLen == recvLen

				// 7.断开客户端连接
			}
		}



	}

	// 8.关闭服务端句柄
	closesocket(sock);



	WSACleanup();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值