Socket服务端涉及知识
- 相关函数,及函数中设计的知识
- 多进程
僵尸进程
关闭多余的socket
程序的退出和资源的释放
日志 - 多线程
客户端,服务端地址
在公网上相互连接时,服务端和客户端相互连接或请求时都是通过公网IP进行的。因此服务端listen到的客户端的IP就是客户端所在的公网IP。客户端recv到服务器发送的信息时得到的是服务器的公网IP。
send函数
- 大于一个字节的传输,都需要做网络字节的转换。
- send函数是会堵塞等待的:当客户端发送过多,而服务端接收量将服务端缓存区填满后send就会堵塞,直到服务端缓存区有容量才会继续。这种情况一般出现在高并发情况下。
TCP报文分包和粘包
- TCP分包:send时,tcp可能自己进行分包发送
- 这种情况长出现在通信过程中,因为send函数和recv函数
都是可指定长度的。解决的办法是自定义一份协议,发送时是报文长度+报文内容,常用发送的报文长度有两种:ASCII码、二进制整数。
报文长度是四个字节,所以ASCII码最大9999个字节,而二进制数可表示2的31次幂+…。故一般采用二进制数作为报文长度。 - 粘包:实现参照freecplus框架中的Writen函数和Readn函数
UDP和TCP在socket编程主要区别
- 接收函数:UDP是recvfrom和recvmsg,TCP是recv
- 发送函数:UDP是sendto和sendmsg,TCP是send
send函数和recv函数发送或读取不完整的情况如何解决
肯定要通过循环执行recv函数。实现参照freecplus框架中的Writen函数和Readn函数
程序在后台运行的两种方法
- 在程序执行语句后加&
- 采用fork()
参考链接
信号
socket中主要用于服务程序的退出。
指定执行某信号:
killall -信号数字 程序名
参考链接
视频链接
信号阻塞:就是过段时间执行信号对应的函数。
功能更强的sigaction.
多线程
文章参考链接
视频参考链接
按顺序创建,执行同样的线程函数,不一定按顺序结束。
使用相同的地址空间,共享全局变量和对象。
线程回收详见上面的参考链接。
网络服务端性能测试
参考链接
主要指标如下:
- 服务端的并发能力
服务端并发性能测试:即可以接受客户端的最大连接数量;重视CPU和内存使用率的变化(磁盘I/O网络、I/O)。 - 服务端的业务处理能力
即每秒可以处理的业务请求数量;重视CPU和内存使用率的变化。注意客户端的数量不要太多,否则大量资源消耗在连接请求上。 - 客户端的业务响应时效
- 网络带宽
注:测试时需要利用到.sh文件。多线程和多进程测试步骤基本相同,重要的是掌握测试过程
I/O复用
和多进程多线程最大的区别就是利用一个线程就可以搞定所有的等待和阻塞。
1. select
当新的客户端连上来时,socket的整型值会按照从小到大找到可用的来分配
服务端正常运行时socket的整型值一般如下图:
服务端gdb调试运行时socket的监听整型值从7开始,后面的规则和非调试运行是一样的。
fd_set的位图bitmap实现:
如果socket的值为3,bitmap的(0,3)会被置为1;如果socket的值为4,bitmap的(0,4)会被置为1;所以select最多只能加入1024个socket。这个bitmap的总大小1024可以调整(调大后效率会降低),但是有poll和epoll,故没有调整的必要。
select里会将传进去的参数FD_SET的bitmap作修改,仅保留发生事件的socket的位。
- select写的问题(第三个参数)
select写的时候有写缓冲区的存在,如果连接上的客户端不接收或接收的慢,那写的操作会发生阻塞,客户端读一些后,服务端会接着再写一批。 - select性能测试
一定要排除网络问题。比如公网IP连接比内网IP连接肯定要慢。要用控制变量法的方式测每一项。
2. Poll
poll也有写缓冲区的问题,类似select的写缓冲区。3.epoll**
如果将监听客户端连接的socket设置了边缘触发,若不对代码做处理(这里的处理指的是I/O的阻塞状态设置为非阻塞,然后accept的地方要加个循环)就会让连接的客户端出现有时间未处理,但是没丢失。
accept、recv、read等函数都能够发生阻塞。
epoll也有写缓冲区的问题,类似select的写缓冲区。