技术沉思录

Android网络编程-TCP/IP协议

字数统计: 2.3k阅读时长: 8 min
2019/06/21

Android网络编程-计算机网络基础一文中得知,IP协议属于网络层,TCP、UDP协议属于传输层。
IP协议是TCP/IP协议族的动力,它为上层协议提供无状态、无连接、不可靠的服务。
TCP协议是面向连接的传输层协议,提供一种面向连接的、可靠的字节流服务。
UDP协议是面向无连接的传输层协议,提供面向事务的简单不可靠信息传输服务。

数据报文

在不同层传输的数据单位名称不同,在网络层传输的叫数据报,在传输层传输的叫报文段。

IP数据报

IP数据报格式如下图:
IP数据报
各个字段的详细说明:

名称 长度 说明
版本 4bit IP协议的版本,目前的IP协议版本号为4,下一代IP协议版本号为6
首部长度 4bit IP报头的长度,最大长度60字节(15*4),
分为固定部分的长度(20字节)和可变部分的长度
服务类型 8bit Type Of Service
总长度 16bit IP报文的总长度。数据报的最大长度为 65535 字节
标识 16bit 它是一个计数器,用来产生数据报的标识。
当IP报文长度超过传输网络的MTU(最大传输单元)时必须分片,
此标识表示同一个数据报的分片。
标志 3bit R、DF、MF三位,目前只有后两位有效。
DF位:为1表示不分片,为0表示分片。
MF:为1表示“更多的片”,为0表示这是最后一片。
片偏移 13bit 本分片在原先数据报文中相对首位的偏移位。
片偏移以8个字节为偏移单位。
生存时间 8bit TTL (Time To Live)表示数据报在网络中的寿命,其单位为秒。
在目前的实际应用中,常以“跳”为单位。
协议 8bit 指出IP报文携带的数据使用的哪种协议,
以便目的主机的IP层能知道要将数据报上交到哪个进程。
TCP的协议号为6,UDP的协议号为17。
ICMP的协议号为1,IGMP的协议号为2.
首部校验和 16bit 计算IP头部的校验和,检查IP报头的完整性。
源地址 32bit 标识IP数据报的源端设备。
目的地址 32bit 标识IP数据报的目的地址。
可选字段 长度可变 1~40 字节,用于增加IP数据报的控制功能。
填充 保证IP首部长度是4字节的整倍数

TCP报文

TCP报文

名称 长度 说明
源端口 16bit 数据发送方的端口号
目的端口 16bit 数据接受方的端口号
序号 32bit 本数据报文中的的第一个字节的序号
(在数据流中每个字节都对应一个序号)
确认号 32bit 希望收到的下一个数据报文中的第一个字节的序号
数据偏移 4bit 表示本报文数据段距离报文段有多远
保留字段 6bit 保留为今后使用,但目前应置为0
紧急比特URG 当值为1时表示次报文段中有需要紧急处理
确认比特ACK 值为1时确认号有效,值为0时确认号无效
复位比特RST 值为1时表示TCP连接存在严重的错误,需要重新进行连接
同步比特SYN 值为1表示这是一个连接请求或连接接受报文
终止比特FIN 值为1表示要发送的数据报已经发送完毕,需要释放传送连接
窗口 16bit TCP连接的一端根据缓存空间的大小来确定自己接受窗口的大小
限制发送放的窗口上限
检验和 16bit 用来检验首部和数据两部分的正确性
紧急指针字段 16bit 紧急指针指出在本报文段中的紧急数据的最后一个字节的序号
选项字段 长度可变 TCP 首部可以有多达40字节的可选信息,
用于把附加信息传递给终点,或用来对齐其它选项

UDP报文

相对于TCP报文,UDP报文简单了很多。
UDP报文

名称 长度 说明
源端口 16bit 数据发送方的端口号
目的端口 16bit 数据接受方的端口号
包长度 16bit UDP首部的长度和数据的长度之和。单位为字节
校验和 16bit 用来检验首部和数据两部分的正确性

TCP三次握手和四次挥手

TCP用三次握手来创建连接,使用四次分手来释放连接。
三次握手

三次握手

三次握手的目的是同步连接双方的序列号和确认号并交换TCP窗口大小的信息。
握手过程:

  1. 第一次握手:建立连接,客户端先发送连接请求报文,将SYN设置为1,Sequence Number为x。客户端进入SYN+SEND状态,等待服务器确认。
  2. 第二次握手:服务器收到SYN报文。服务器收到客户端的SYN报文,需要对这个SYN报文进行确认,设置Acknowledgment Number为x+1(Sequence+1);同时,自己还要送法SYN消息,将SYN位置为1,Sequence Number为y;服务器将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN+RECV状态。
  3. 第三次握手:客户端收到服务器的 SYN+ACK报文段。然后将Acknowlegment Number设为y+1,向服务器发送ACK报文段,这个报文段发送完毕后,客户端端服务器都进入ESTABLISHED状态,完成TCP三次握手。

完成了三次握手,客户端和服务器就可以开始传送数据了。

四次挥手

当客户端和服务端传输数据完毕后,需要断开TCP连接。TCP断开的过程,就是四次挥手。

  1. 第一次挥手:客户端(也可以是服务器),设置Sequence Number和Acknowledgment Number,向服务器发送一个FIN报文段。此时客户端进入FIN_WAIT_1状态;这表示客户端没有数据发送给主机了。
  2. 第二次挥手:服务器收到客户端发来的FIN报文段,向客户端回一个ACK报文段,Acknowledgement Number为Sequence Number加1;客户端进入FIN_WAIT_2状态,服务器进入CLOSE_WAIT状态;服务器告诉客户端,我同意你的”关闭”请求。
  3. 第三次挥手:服务器向客户端发送FIN报文段,请求关闭连接,同时服务器进入LAST_ACK状态。
  4. 第四次挥手:客户端收到服务器发送的FIN报文段,向主机发送ACK报文段,然后客户端进入TIME_WAIT状态,服务器收到客户端的ACK报文段以后,就关闭连接,此时,客户端等待2MSL后一次没有到收到回复,则证明服务端已正常关闭,那好,客户端也可以关闭连接了。

TCP三次握手的必要性

防止服务器端因接收了早已失效的连接请求报文,从而一直等待客户端请求,最终导致形成死锁、浪费资源。

TCP四次挥手的必要性

为了保证通信双方都能通知对方,需释放、断开连接。

为什么客户端关闭连接前要等待2MSL时间

MSL: 最大报文段生存时间

四个报文发送完毕后,就可以直接进入CLOSE状态了,但是有可能网络是不可靠的,一切都可能发生,比如有可能最后一个ACK丢失。所以TIME_WAIT状态是用来重发可能丢失的ACK报文。展开具体来讲:

  • 为了保证客户端发送的最后1个连接释放确认报文 能到达服务器,从而使得服务器能正常释放连接。
  • 防止早已失效的连接请求报文,出现在本连接中。客户端发送了最后1个连接释放请求确认报文后,再经过2MSL时间,则可使本连接持续时间内所产生的所有报文段都从网络中消失。

TCP、UDP比较

TCP UDP
可靠性 可靠 不可靠
连接性 面向连接 无连接
报文 面向字节流 面向报文
效率 低效 高效
双工性 全双工 一对一,一对多,多对一,多对多
支持多播和广播
流量控制 滑动窗口机制
拥塞控制 慢开始/拥塞避免
快重传/快恢复
传输速度
应用场景 效率要求相对低,准确要求相对高。
要求有连接的场景
效率要求相对高,准确要求相对低
应用 SMTP,TELNET,HTTP,FTP DNS,RIP,NFS,SNMP,
IP电话,流媒体

参考

CATALOG
  1. 1. 数据报文
    1. 1.1. IP数据报
    2. 1.2. TCP报文
    3. 1.3. UDP报文
  2. 2. TCP三次握手和四次挥手
    1. 2.1. 三次握手
    2. 2.2. 四次挥手
    3. 2.3. TCP三次握手的必要性
    4. 2.4. TCP四次挥手的必要性
      1. 2.4.1. 为什么客户端关闭连接前要等待2MSL时间
  3. 3. TCP、UDP比较
  4. 4. 参考