TCP和UDP 三次握手,四次挥手
Posted *^O^*—*^O^*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP和UDP 三次握手,四次挥手相关的知识,希望对你有一定的参考价值。
端口号
在TCP/IP协议中, 用 "源IP", "源端口号", "目的IP", "目的端口号", "协议号" 这样一个五元组来标识一个通
信(可以通过netstat -n查看)——(这里的协议是应用层协议);
0 - 1023: 知名端口号, HTTP, FTP, SSH等这些广为使用的应用层协议, 他们的端口号都是固定的.
1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作系统从这个范围分配的.
- 一个进程是否可以绑定多个端口号?
可以绑定多个端口号 - 一个端口号是否可以被多个进程绑定?
不可以
UDP
UDP协议端格式
UDP的特点
(1)无连接,不可靠
(2)面向数据报(只能一次发送,一次接收)
(3)有接收缓冲区,没有发送缓冲区
(4)大小受限(不能超过64k)
我们注意到, UDP协议首部中有一个16位的最大长度. 也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部).然而64K在当今的互联网环境下, 是一个非常小的数字.如果我们需要传输的数据超过64K, 就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装;
基于UDP的应用层协议
NFS: 网络文件系统
TFTP: 简单文件传输协议
DHCP: 动态主机配置协议
BOOTP: 启动协议(用于无盘设备启动)
DNS: 域名解析协议
UDP的缓冲区
UDP没有真正意义上的 发送缓冲区. 调用sendto会直接交给内核, 由内核将数据传给网络层协议进行后续的传输动作;
UDP具有接收缓冲区. 但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致; 如果缓冲区满了, 再到达的UDP数据就会被丢弃;
UDP的socket既能读, 也能写, 这个概念叫做 全双工;
网络编程(客户端服务端网络数据传输)都是基于网络IO的操作,往网卡上发送数据缓冲区可以使用,也可以不使用,使用缓冲区就是多次发(write)到缓冲区,缓冲区真正的发到网络(flush)
TCP协议
TCP全称为 “传输控制协议(Transmission Control Protocol”). 人如其名, 要对数据的传输进行一个详细的控制;
TCP设计的时候,就是综合了安全性/可靠性。
这里TCP的效率高于UDP,在保证传输安全的前提下,尽可能的提高传输效率(多线程也是这种设计原则)
TCP协议段格式
源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去;
32位序号/32位确认号:
4位TCP报头长度: 表示该TCP头部有多少个32位bit(有多少个4字节); 所以TCP头部最大长度是15 * 4
= 60
16位窗口大小:
16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含
TCP首部, 也包含TCP数据部分.
16位紧急指针: 标识哪部分数据是紧急数据;
40字节头部选项;
6位标志位:
URG: 紧急指针是否有效
ACK: 确认号是否有效
PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走
RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段
FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段
确认应答(ACK)机制
发送数据时编号,1~1000个字节,保存在TCP的32位序号字段
应答方式:下一个是多少,接收到的数据序号最大值+1
含义:下一个是多少,表示之前的数据都已经接收保存在TCP ack标志位=1
超时重传机制
发送端发送的数据报超过一定的时间间隔没有收到确认影带的数据报,表示之前发送的数据可能丢包,所以要重新发送(发送的数据报丢包,确认应答的数据报丢包):
原因就是发送端不能无限期的等待
如何确定超时时间?
系统动态计算,初始有一个默认超时时间(500ms),每次重传,超时时间会在上一个超时间基础上*2;
重传达到一定的次数后,认为无法正常发送数据,关闭连接;
连接管理机制(安全机制)
连接:客户端和服务端,每一端来说,保持一个本端到对端的连接状态(有方向的)
建立连接:
建立客户端到服务端的连接(连接状态保存在客户端)
建立服务端到客户端的连接(连接状态保存在服务端)
三次握手的流程(建立连接)
(1)客户端发送syn数据到服务端,申请建立客户端到服务端的连接
(2)服务端返回syn+ack给客户端(这里的数据报可以合并):ack是对于第一次syn的应答,syn是申请建立服务端到客户端的连接, 客户端收到该数据报建立客户端到服务端的连接
(3)客户端返回ack给服务端:ack是对第二次syn的应答,服务端收到该数据报,建立服务端到客户端的连接
四次挥手的流程(关闭连接)
(1)客户端发送fin到服务端,申请关闭连接(客户端到服务端的连接),服务端接收到该数据报,状态置为 close_wait
(2)服务端返回ack给客户端;ack是对于第一次fin的应答,返回ack,是操作系统实现tcp协议栈的时候,默认的机制,系统自动返回
(3)服务端发送fin到客户端,申请关闭连接(服务端到客户端的连接),客户端接收到该数据报,状态置为time_wait;程序手动调用close关闭连接(发送fin)
(4)客户端返回ack给服务端;ack是对第三次fin的应答
为什么是四次挥手?能不能是三次?
答:第二次是系统自动返回,第三次是程序手动调用close关闭连接才返回
那么为什么不能合并?TCP协议栈实现时,就不包含主动的发fin,交给程序自己实现,程序在关闭前,可以完成一些前置工作,如释放资源等操作。
在四次挥手的二三步,客户端为什么不能置为关闭状态?第三步,客户端接收到fin以后,为什么还不能置为关闭状态,而是要等待一段时间,才关闭?
答:第四步的ack也可能丢包,在这种情况下,服务端会基于超时重传机制,重发fin,如果客户端关闭连接,就没法处理这个数据报了;
服务器出现大量的close_write状态,什么意思,怎么解决?
答:服务端程序没有正确调用close关闭连接,只需要加上对应的 close 即可解决问题;
为什么TIME_WAIT的时间是2MSL
答:MSL是TCP报文的最大生存时间, 因此TIME_WAIT持续存在2MSL的话就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失(否则服务器立刻重启,
可能会收到来自上一个进程的迟到的数据, 但是这种数据很可能是错误的);
同时也是在理论上保证最后一个报文可靠到达(假设最后一个ACK丢失, 那么服务器会再重发一个FIN. 这时虽然客户端的进程不在了, 但是TCP连接还在, 仍然可以重发LAST_ACK);
以上是关于TCP和UDP 三次握手,四次挥手的主要内容,如果未能解决你的问题,请参考以下文章