C++创建一个简单的tcp服务端

一:创建一个socket
二:创建一个地址
三:将地址与socket绑定
四:对当前socket进行监听
五:等待接受客服端的连接
六:开辟工作线程

下面代码就是 一socket一线程 的逻辑

#include <sys/socket.h>
#include <iostream>
#include <netinet/in.h>
#include <unistd.h>	   //close(server_fd)
#include <string.h>	   //	memset
#include <arpa/inet.h> //	inet_ntoa
#include <thread>

void workthread(int client_fd)
{
	if (client_fd != -1)
	{
		while (true)
		{
			char readbuff[1024] = {0};
			int readlen = recv(client_fd, readbuff, sizeof(readbuff), 0);
			std::cout << "rec:" << readbuff << std::endl;
			/*do some work*/
			send(client_fd,readbuff,readlen,0);
		}
	}
}
int main(int argc, char **argv)
{

	if (argc != 2)
	{
		std::cout << "application only accepts one parameter" << std::endl;
		return -1;
	}

	std::cout << "input par: " << argv[1] << "," << std::endl;
	char *appname = argv[0];
	int port = atoi(argv[1]);
	//第一步
	int server_fd = socket(AF_INET, SOCK_STREAM, 0);

	//第二步
	sockaddr_in serveraddr;
	memset(&serveraddr, 0, sizeof(sockaddr_in));
	serveraddr.sin_port = htons(port); //本地转网络字节序
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = INADDR_ANY; //0.0.0.0 代表监听本机的所有地址

	//第三步
	//sockaddr_in 与sockaddr的含义差不多,只是sockaddr_in  将端口和ip分开了
	if (0 != bind(server_fd, (sockaddr *)&serveraddr, sizeof(sockaddr_in)))
	{
		return -1;
	}
	//第四步
	if (0 != listen(server_fd, 5)) //5代表同一时刻最大的监听个数
	{
		return -1;
	}

	while (true)
	{
		//第五步
		sockaddr_in client_addr;
		socklen_t client_addrlen;
		int client_fd = accept(server_fd, (sockaddr *)&client_addr, &client_addrlen);

		std::cout << "client ip:" << inet_ntoa(client_addr.sin_addr) << std::endl;
		std::cout << "client port:" << client_addr.sin_port << std::endl;

		//第六步
		std::thread thread(workthread, client_fd);
		thread.detach();
	}

	close(server_fd);
	return 0;
}

linux下一个线程大概占用4M内存,假设一台服务器的内存为8G,以资源的使用率不超过80%考虑,那么他能支持同时创建的8x1024x0.8 /4 = 1638.4个线程,如果不需要同时处理超过 1638 个客户端连接的时候,以上代码的处理逻辑不会有任何问题,反之则会存在卡死崩溃的问题。

如何解决呢?

首先要明白问题出现的原因,当多个连接同时进入服务器时:
1、卡死主要体现在单线程监听时需要阻塞等待新的连接

解决的方式可以使用一个多路复用的底层实现


2、崩溃主要体现在开辟的线程过多,导致资源消耗过多,
解决方式可以使用一个线程池

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dai1396734

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值