一、简介
本实验采用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