网络编程 (二)
网络编程 (二)
三次握手和四次挥手
TCP 是面向连接的安全的数据传输,在客户端与服务端建立连接的时候要经过三次握手的过程,在客户端与服务端断开连接的时候要经历四次挥手 的过程,下图是客户端与服务端的三次握手建立连接,数据传输和断开连接四次挥手 的全过程。

上图中 ACK 表示确认序号,确认序号的值是对方发送得到序号值 + 数据长度,特别注意的是 SYN 和 FIN 本身也会占用一位
注:
SYN —> synchronous
ACK —> acknowledgement
FIN —> finish
三次挥手和四次握手的过程都是在内核实现的。

通信的时候不再需要 SYN 标识位了,只有在请求连接的时候需要 SYN 标识位
传输数据的时候随即序号 seq 就是最近一次对方发送给自己的 ACK 的随即序号值,而发给对方的 ACK 就是上次刚刚发给对方的 ACK 值
图中发送的 ACK 确认包表示给对方发送数据的一个确认,表示你发送的数据我都收到了,同时告诉对方下次发送该序号开始的数据
由于每次发送数据都会受到对方发来的确认包,所以可以确认对方是否收到了,如果没有收到对方发来的确认包,则会进行重发。
mss:最大报文长度, 只是在建立连接的时候, 告诉对方我最大能够接收多少数据, 在数据通信的过程中就没有mss了
win:表示告诉对方我这边缓存大小最大是多少
滑动窗口
主要作用:段东窗口主要是进行流量控制的
见下图:如果发送端发送的速度较快,接收端接收到数据后处理的速度较慢,而接收缓冲区的大小是固定的,就会导致接受缓冲区满而丢失数据。TCP 协议通过 “滑动窗口 (Sliding Window)” 机制解决这一问题
在客户端给服务端发包的时候,不一定是非要等到服务端发送响应包,由于客户端知道服务端的窗口大小,所以可以持续多次发送,当发送数据达到对方窗口大小了就不再发送,需要等到对方进行处理,对方处理之后可继续发送。
MTU:最大传输单元 (Maximum Transmission Unit)
是指一种通信协议的某一层上面所能通过的最大数据包大小 (以字节为单位)。最大传输单元这个参数通常与通信接口有关 (网络接口卡、串口等),这个值如果设置为太大会导致丢包重传的数据较大,图中的最大值是 1500,其实是一个经验值。
粘包的概念
粘包:多次数据发送,首尾相连,接收端接受的时候不能正确区分第一次发送多少,第二次发送多少。
解决方案:
- 方案1:包头 + 数据
如 4 位的数据长度 + 数据 —-> 00101234567890
其中 0010 表示长度,1234567890 表示 10 个字节长度的数据。
另外,发送端和接收端可以协商更为复杂的报文机构,这个报文结构就相当于双方约定的一个协议。 - 方案2:添加结尾标记
如结尾最后一个字符为 \n $ 等 - 方案3:数据包定长
如发送方和接收方约定,每次只发送 128 个字节的内容,接收方接受定长 128 个字节就可以了。
高并发服务
由于 accept 和 read 函数都会阻塞,如当 read 的时候,不能调用 accept 接受新的连接,当 accept 阻塞等待的时候不能 read 读数据
如何支持多并发的服务:
- 第一种方案:使用多进程,可以让父进程接受新连接,让子进程处理与客户端通信
- 思路:让父进程 accpet 接收新连接,然后 fork 子进程,让子进程处理通信,子进程处理完成后退出,父进程使用 SIGCHLD 信号回收子进程。
- 第二种方案:使用多线程,让主线程接收新连接,让子线程处理与客户端通信;使用多线程要将线程设置为分离属性,让子线程在退出之后自己回收资源。
- 第三种方案:可以将 accept 和 read 函数设置为非阻塞,调用 fcntl 函数可以将文件描述符设置为非阻塞,然后再 while 循环中忙轮询。