C++实现TCP Server 多线程同时连接多个客户端

一、简介
本实验采用c++实现了tcp Server,采用多线程的方式可以同时与多个客户端通讯。其中主线程阻塞接收客户端连接,收到连接后开辟一个子线程做相应处理。

二、代码


#include   
#include   
#include 
#define MAXCLIENTNUM 100	//服务端连接客户端个数限制
#include 
using namespace std;
#pragma comment(lib,"ws2_32.lib")  

typedef struct ClientInf//客户端信息 使用结构体是为了方便信息变量的扩展
{
     
	SOCKET client_socket;
}ClientInf;

DWORD WINAPI Thread(LPVOID lpParameter) //子线程函数
{
      	
	while (true)//循环
	{
     
		//接收数据  
		ClientInf client_inf = *(ClientInf *)lpParameter;
		char rev_data[255];
		int ret = recv(client_inf.client_socket, rev_data, 255, 0);

		if (ret > 0)
		{
     
			rev_data[ret] = 0x00;

			printf(rev_data);
		}

		//解析
		/*这里对接收数据进行解析*/

		//处理
		/*解析后进行处理*/

		//处理后回发数据  
		const char * sendData = "$Server Send OK\r\n";
		send(client_inf.client_socket, sendData, (int)strlen(sendData), 0);
	}
	return 0; 
}


int main(int argc, char* argv[])
{
     
	int y = 0;
	//初始化WSA  
	WORD sockVersion = MAKEWORD(2, 2);//使用winsocket2.2版本

	WSADATA wsaData;

	if (WSAStartup(sockVersion, &wsaData) != 0)
	{
     
		return 0;
	}

	//创建服务端套接字  
	SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	
	if (slisten == INVALID_SOCKET)
	{
     
		printf("socket error !");

		return 0;
	}

	//绑定IP和端口  
	sockaddr_in sin;

	sin.sin_family = AF_INET;

	sin.sin_port = htons(3000);

	sin.sin_addr.S_un.S_addr = INADDR_ANY;

	if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)//绑定
	{
     
		printf("bind error !");
	}

	//开始监听  
	if (listen(slisten, 5) == SOCKET_ERROR)
	{
     
		printf("listen error !");

		return 0;
	}

	ClientInf client_inf_vector[MAXCLIENTNUM];//包含所有已连接的客户端
	HANDLE thread_handle_vector[MAXCLIENTNUM];//每个客户端线程句柄集合
	int client_num = 0;//已连接客户端数量

	//主线程
	while (true)
	{
     
		printf("等待连接...\n");

		sockaddr_in remoteAddr;

		int nAddrlen = sizeof(remoteAddr);

		SOCKET c_socket = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);//阻塞等待

		if (client_num < MAXCLIENTNUM)
		{
     
			if (c_socket == INVALID_SOCKET)
			{
     
				printf("accept error !");
				continue;
			}
			client_inf_vector[client_num].client_socket = c_socket;
			char sendBuf[20] = {
      '\0' };

			printf("接受到一个连接:%s:%d\r\n", inet_ntop(AF_INET, (void*)&remoteAddr.sin_addr, sendBuf, 16), remoteAddr.sin_port);

			thread_handle_vector[client_num] = CreateThread(

				NULL,

				0,

				Thread,

				&(client_inf_vector[client_num]),

				0,

				NULL

			);
			client_num++;
			printf("当前已连接客户端数量:%d\r\n", client_num);
		}
		else
		{
     
			printf("当前连接数量已达上限:%d\r\n", client_num);
		}
	}

	//退出前的操作
	for (int i = 0; i < client_num; i++)//关闭所有客户端
	{
     
		closesocket(client_inf_vector[i].client_socket);
	}

	closesocket(slisten);//关闭服务端

	WSACleanup();

	return 0;
}

三、源码下载
链接:https://pan.baidu.com/s/1vnc7Oi3bUKcbVPmOCLDR-g
提取码:czep

你可能感兴趣的:(通讯技术,socket,多线程)