一:
C++服务器的开发中有比较多现成的框架,比如游戏服务器中常用的skynet。但是在为一些智能门锁,或者些小批量的电子产品(几千台到2万台左右)的话,我们可以自己设计个简单的服务器,不需要拿现成的框架来做(毕竟熟悉一个框架得要比较长的时间)。
二:
下面是简易TCP服务器设计的要点:
(1)网络报文的数据格式
首先得协调好双方(客户端和接收端)的通信的数据结构,如果客户端是C/C++实现的类型,那么通信的双方(客户端和接收端)数据类型可以用结构体;但是现在多数的终端可能是java或者android实现的,一般的话可以定义这样的数据类型:
[HNYY5G123456789,23,GPS...]
// 一个数据的开头用上“ [ ” ,结尾用上“ ] ”
//HNYY5G是表示公司名称缩写
//123456789,这个表示设备的ID,设备ID的获取可以是IMEI号或者别的
//23表示这个当前数据后面对应的数据的长度
这样的话,客户端发送的数据就按定义上面的定义;服务器(C++)要识别到一个完整的数据的话,就用 ” [ “ 和 ” ] “,这个可以用到函数split。
(2)IO多路复用机制的选择
select,poll,epoll这3个的选择。
在linux下,毫无疑问就是使用epoll;(也要设置为非阻塞)
在windows server 2008上,可以使用select;(也要设置为非阻塞)
(3)网络粘包的解决
为啥会产生网络的粘包?
在网络发送端socket有个发送缓冲区,这个缓冲区不是一有数据过来就调用send函数,并执行这个函数把数据发送到服务端的,而是等到缓冲区满或者到一定的时间点才发送的。接收端对应的socket也有个缓冲区,这个缓冲区也不大(好像是几十K吧),而我们接收端就使用recv函数来取出数据。而当服务器的数据发送太过频繁的话,但是接收端使用recv(这个接收数据是从缓冲区取出数据的)每次取出的数据量比较小的话,比如执行一次recv才取出几K的话,这时候就会出现缓冲区数据的溢出。这样的话也出现所说的粘包问题。
解决的方法就是recv一次取出的数据差不多和接收缓冲区的大小一样。如下的代码:
char recvbuf[4096*10];
int ret=recv(fd, recvbuf,sizeof(recvbuf), 0) ;
//ret返回接收到数据的个数,fd表示socket
(4)内存池
为啥要有内存池?
因为服务器是要长期的运行的,程序在运行的过程中难免产生内存碎片,久而久之,会使内存的可使用空间变小,因此为了服务器的高可用性。我们得设计个简单的内存池,程序变量所需要的空间都从这个设计的内存池里面分配,当变量的生命周期结束的时候,就将这块内存的数据清除,回收。
而对于C++11,由于引入了智能指针,对于对象的管理,可以直接使用智能指针来管理,这时候设计服务器程序可以不使用内存池。
(5)线程池
引入线程池,是在服务器程序启动时,就有已经分配好的线程,当需要线程的时候,就从线程池里面分配取出线程,这样的话,就避免频繁创建和销毁线程带来系统的开销。
(6)心跳检测
为啥要引入心跳检测?
服务器在管理多个客户端的时候,当某些客户端长期不发送数据,或者掉线了。服务还在维护这些客户端,这样的话会造成性能的下降(每执行一次select或者epoll都要检测这些已经掉线的客户端)和资源的浪费,这样的话就得引入心跳检测。心跳检测就是检测客户端在一定的时间内是否有数据到达,或者规定的心跳数据类型到达(比如 :[HNYY5G123456789,2,LK] ,LK就是规定的心跳数据标识),没有过的话就的把该客户端从服务器管理的网络IO(也就是客户端的socket)中删除。
(7)日志系统
服务器程序的运行,难免会产生些不可以避免的问题。而排查这些问题,得用到这些错误的信息,因此服务器得有个日志系统,也就是打印log的类。
服务器并不只是单进程或者单线程的,打印log的类得要单例模式来实现,还得在程序跑起来之前这个类就要生成了。
(8)性能的检测
注:发送和接收这两个函数的性能是不对等的。如下是我机器上的数据:
send这个函数发送的上线是每秒发送130W左右的数据包;
recv这个函数接收的上线是每秒可以接收430W个数据包;
如何模拟多个客户端的连接?因为服务器要在真实的场景跑起来的话,是有大量的客户端连接的。客户端这边的话,用一个类来实现,然后定义一个类的数组,这个数组的连接,发送,接收数据放在一个死循环体内while(1) { ....... },这样就模拟了多个客户端数据的发送的测试。
同样的,模拟大数据的发送,就把一个数据的内容变得比较大 (几十K),同样服务端的数据类型也更改,这样就能完成大额数据的发送,来测试服务器的性能。
原文:https://www.cnblogs.com/Unclebigdata/p/14408875.html