Android网络编程(三):TCP、UDP协议

简介

TCP和UDP协议都位于OSI七层模型中的传输层,处于IP协议的上一层,隶属于TCP/IP协议簇,如果你不清楚TCP/IP协议,请看我写的另外一篇文章:Android网络编程(二):TCP/IP协议详解

TCP和TCP是传输层的两个主要协议,互为补充,都是用于处理数据包。UDP支持无连接传输,是不可靠的,但是传输性能好;TCP是面向连接的,可靠性更高,用得也最多。

Android网络编程(三):TCP、UDP协议

UDP协议

UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

UDP不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的QQ就是使用的UDP协议。

UDP应用场景:
1.面向数据报方式
2.网络数据大多为短消息
3.拥有大量Client
4.对数据安全性无特殊要求
5.网络负担非常重,但对响应速度要求高

TCP协议

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
Android网络编程(三):TCP、UDP协议
TCP头部消息
Android网络编程(三):TCP、UDP协议

  1. 源、目标端口号字段:占16比特。TCP协议通过使用”端口”来标识源端和目标端的应用进程。端口号可以使用0到65535之间的任何数字。在收到服务请求时,操作系统动态地为客户端的应用程序分配端口号。在服务器端,每种服务在”众所周知的端口”(Well-Know Port)为用户提供服务。

  2. 顺序号字段:占32比特。用来标识从TCP源端向TCP目标端发送的数据字节流,它表示在这个报文段中的第一个数据字节。

  3. 确认号字段:占32比特。只有ACK标志为1时,确认号字段才有效。它包含目标端所期望收到源端的下一个数据字节。

  4. 头部长度字段:占4比特。给出头部占32比特的数目。没有任何选项字段的TCP头部长度为20字节;最多可以有60字节的TCP头部。

  5. 标志位字段(U、A、P、R、S、F):占6比特。各比特的含义如下:

    ◆URG:紧急指针(urgent pointer)有效。
    ◆ACK:为1时,确认序号有效。  
    ◆PSH:为1时,接收方应该尽快将这个报文段交给应用层。  
    ◆RST:为1时,重建连接。
    ◆SYN:为1时,同步程序,发起一个连接。  
    ◆FIN:为1时,发送端完成任务,释放一个连接。

  6. 窗口大小字段:占16比特。此字段用来进行流量控制。单位为字节数,这个值是本机期望一次接收的字节数。

  7. TCP校验和字段:占16比特。对整个TCP报文段,即TCP头部和TCP数据进行校验和计算,并由目标端进行验证。

  8. 紧急指针字段:占16比特。它是一个偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。

  9. 选项字段:占32比特。可能包括”窗口扩大因子”、”时间戳”等选项。

TCP建立三次连接的过程(三次握手)

TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答 SYN + ACK ,并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接,TCP 使用的流量控制协议是可变大小的滑动窗口协议。

TCP三次握手的过程如下:
Android网络编程(三):TCP、UDP协议

  1. 客户端发送 SYN(SEQ=x)报文给服务器端,进入 SYN_SEND 状态。
  2. 服务器端收到 SYN 报文,回应一个 SYN (SEQ=y)ACK(ACK=x+1)报文,进入 SYN_RECV 状态。
  3. 客户端收到服务器端的 SYN 报文,回应一个 ACK(ACK=y+1)报文,进入 Established 状态。

三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。

三次握手可以简单理解为A、B两人开始连麦开黑:

A:听到吗? (第一次握手)
B:听得到,你能听到我的声音吗? (第二次握手)
A:能听到。 (第三次握手)

ok,麦没问题,开始游戏

TCP终止连接过程(四次挥手)

  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其***为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的***seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
  3. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的***为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的***是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  4. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

Android网络编程(三):TCP、UDP协议
四次挥手可以简单地理解为A、B两人结束对话:

A:我已经讲完了。 (第一次挥手)
B:知道啦。 (第二次挥手)
B:但是我还没讲完,我跟你讲哦%#¥#¥%#… (A在听B讲完)
B:我讲完啦。 (第三次挥手)
A:收到。 (第四次挥手)

然后各回各家,各找各妈

上一篇:Android网络编程(二):TCP/IP协议详解
目录:Android网络编程系统性学习目录