目录
前言
传输层协议主要有两个,分别是UDP协议和TCP协议。
一、端口号
1、概念
端口号(Port)标识了一个主机上进行通信的不同的进程。在TCP/IP协议中, 用 "源IP", "源端口号", "目的IP", "目的端口号", "协议号" 这样一个五元组来标识一个通信。
2、相关命令
netstat:
netstat是一个用来查看网络状态的重要工具。
语法:netstat [选项]
功能:查看网络状态
常用选项:
- n 拒绝显示别名,能显示数字的全部转化成数字
- l 仅列出有在 Listen (监听) 的服務状态
- p 显示建立相关链接的程序名
- t (tcp)仅显示tcp相关选项
- u (udp)仅显示udp相关选项
- a (all)显示所有选项,默认不显示LISTEN相关
pidof:
在查看服务器的进程id时非常方便。
语法:pidof [进程名]
功能:通过进程名, 查看进程id
二、UDP协议
1、UDP数据报格式
- 16位UDP长度, 表示整个数据报(UDP报头+UDP数据)的最大长度。UDP报头的大小是固定的,所以通过UDP长度就可以得知报头和数据的大小,从而实现解包。
- 如果校验和出错, 就会直接丢弃。
- 传输层协议可以根据报头中的16位端口号找到相应进程,把数据交给上层应用,完成与应用层的交互。
我们注意到, UDP协议首部中有一个16位的最大长度。也就是说一个UDP能传输的数据最大是64K(包含UDP首部)。然而64K在当今的互联网环境下, 是一个非常小的数字。如果我们需要传输的数据超过64K, 就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装。
2、UDP的特点
- 无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接。
- 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息。
- 面向数据报,不能够灵活的控制读写数据的次数和数量。面向数据报的意思是UDP会把应用层给的数据原封不动的传输过去,既不会拆分也不会合并。如果发送端调用一次sendto, 发送100个字节, 那么接收端也必须调用对应的一次recvfrom, 接收100个字节; 而不能循环调用10次recvfrom, 每次接收10个字节。就好比写信一样,寄一封对方就得收一封,不能收半封。
3、UDP的缓冲区
- UDP没有真正意义上的 发送缓冲区.。调用sendto会直接交给内核, 由内核将数据传给网络层协议进行后续的传输动作。
- UDP具有接收缓冲区。但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致; 如果缓冲区满了, 再到达的UDP数据就会被丢弃。
UDP的socket既能读, 也能写, 这个概念叫做全双工。全双工的意思是recvfrom和sendto可以同时被调用。
三、TCP协议
1、TCP数据报格式
各部分用途:
- 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去。
- 4位TCP报头长度: 表示该TCP头部有多少个4字节,例如首部长度为0101,那么报头长度就是4*5=20。指导报头大小后就能进行解包。
- 16位窗口大小:在应答时表明自己的接收缓冲区的剩余空间。
- 16位校验和:其目的是为了发现TCP首部和数据在发送端到接收端之间是否发生改动。如果接收方检测到校验和有差错,则TCP段会被直接丢弃。
其余部分后面详细介绍。
2、确认应答(ACK)机制
TCP是可靠的,所以发送下一个数据前必须确认对方已经收到之前的数据。所以每次再发送数据后,都需要对方主机进行应答,来表明已经收到数据。
主机A发送数据给B之后, 可能因为网络拥堵等原因, 数据无法到达主机B。如果主机A在一个特定时间间隔内没有收到B发来的确认应答, 就会进行重发。当然传回来的应答也可能丢掉,这个情况下即便B已经收到数据但A不知道,依旧会重发数据,要百分之百确保B收到了上一条数据。重复的数据OS会根据32位序号进行去重操作。
32位序号和32位确认序号:
- 因为传输路径等问题,有时候先发送的数据反而会后到达,导致应答顺序错乱。为了对方主机能够准确无误的应答对应的信息,每条信息都会带一个序号,也就是数据报中的32位序列,对方主机会根据序列号对数据进行排序。
- 对方主机在应答的时候也会发送一个序号,存在32位确认序号中。同一条数据的应答序号要比发送序号大1。也就是A给B发送的报文序号为3,那B给A发送的报文中应答序号就应该为4,告诉A 4之前的数据已经全部收到了,下次请从4开始发送。
- B给A发送的报文中除了有应答序号外依然可以有数据,也可以有发送序号,也就是说确认应答的同时也可以给对方传递数据,同样对方也是如此,这种机制叫做捎带应答。这样就实现了双向通信。tcp也是一个全双工通信协议。
tcp是面向字节流的,TCP将每个字节的数据都进行了编号,即为序列号。我们可以理解成有一个数组以字节为单位线性的存储了缓冲区的数据,每个字节对应一个下标。每个报文在发送时会携带一串数据,这个报文的序号为这一串数据对应的最大下标。发送下一串数据时就能通过下标锁定起始位置。
3、缓冲区
TCP协议是自带发送和接收缓冲区的。用户层在进行write/send操作时,并不是把数据发到网络中,而是拷贝到TCP协议的缓冲区中。用户层接收数据时同理,也是直接从TCP协议的缓冲区