前一段时间刚开学,学校里的事忙了一周多,书接上回,今天说TCP
TCP是面向连接、可靠的网络通信协议。
通信前要三次握手建立连接:
-
主动连接方,发SYN包,告诉对方我想建立连接
-
被动接收方回复SYN+ACK,意思:收到你的请求,我也同意连接
-
发起方再回一个ACK,确认收到对方同意,连接正式建立
TCP套接字函数
分客户端(发端)和服务器:
-
socket:创建套接字,相当于拿到通信的文件描述符,SOCK_STREAM代表TCP。
-
connect:客户端用,用来向服务器发起连接请求,成功返回0。
-
send:发送数据。参数里填套接字、数据缓冲区地址、数据长度,flags默认写0;成功返回实际发出去多少字节,失败返回-1。
-
recv:接收数据。参数是套接字、存放数据的缓存、最多收多少字节;成功返回收到字节数,返回0代表对方关掉连接,-1代表出错。
-
listen:服务器用,开启监听,等待别人连过来。backlog参数是等待连接队列最大数量。
-
accept:服务器调用,取出监听队列里的连接,成功之后返回一个新套接字,专门用来和这个客户端收发数据。
TCP粘包问题
TCP是流传输,没有天然数据包边界。连续多次send发数据时,操作系统可能把好几段数据合并在一起一次性发给接收方,这就是粘包。
解决办法:
-
加延时(不推荐,不稳定)
-
设置分隔符,比如\r\n区分两条消息
-
定长数据包(就像你52单片机7字节固定帧,最常用)
TCP头部
TCP头部最小20字节。里面有源端口、目的端口、32位序号、32位确认序号;还有标志位:
• SYN:请求建立连接
• ACK:确认应答,ACK=1的时候确认序号才生效
• FIN:结束连接
• RST:重置、断开连接
• PSH:推送数据
• URG:紧急数据
四次挥手(断开连接)
用来安全关闭TCP连接。
-
主动关闭一方,发FIN,告诉对方:我这边不再发新数据
-
被动方回复ACK,确认收到关闭请求,被动方还能继续发剩下的数据
-
被动方数据发完之后,发FIN,告诉对方我这边也发完了
-
主动方回复ACK,连接正式关闭
特殊情况:被动方刚好数据发完,ACK和FIN合并,四次挥手简化成三次。
TCP保证可靠传输的机制
-
序号 + 确认序号:每一段数据编号。接收方收到数据,回复确认号,告诉发送方我收到哪了,下次从哪开始发,保证数据完整不乱序、不丢包。
-
滑动窗口:做流量控制。通过窗口大小,限制发送方发送速度,别发太快把接收端挤爆。
-
拥塞控制:网络拥堵的时候自动降速,保证网络稳定可靠。
-
保活掉线检测:连接建立之后长时间空闲,TCP会检测对方在线状态,判断连接有没有断。
TCP 和 UDP对比
UDP:无连接,实现简单,占用资源少;不可靠,不保证数据一定送到。
TCP:有连接,机制复杂,资源开销更大;可靠传输,保证数据准确、有序送达。