浅析TCP与UDP

来源:互联网 发布:分润系统源码 编辑:程序博客网 时间:2024/05/18 00:09

无连接运输:UDP

UDP是面向无连接的协议,它只负责将数据传输给客户端,而不会保证数据的完整性。这种特性导致其在Web应用程序方面很是吃亏,所以说Web应用程序使用都为TCP连接,但是在音频传播和实时视频传播方面,UDP确是可以做到比TCP更好的效果,虽然也会发生数据丢失,但是少量数据的丢失对于声音和视频的效果显示没有太大的影响.

UDP的套接字

一个UDP套接字由一个二元组来进行标识,该二元组包括一个目的IP地址和一个目的端口号.

  • 源端口号用途
    当A到B的报文段中,源端口号作为返回地址的一部分,即当B要回发一个报文段给A时,B到A的报文段的目的端口号便从A到B的源端口号中取值.

UDP的优点

  • 关于何时、发送什么数据的应用层控制更加精细
    使用UDP的时候,应用程序只需要将数据交给UDP,然后UDP将其打包进报文段,然后传递给网络层,不管数据能不能到达,UDP依然会发送没有发送的数据,而TCP不同,TCP有一个数据重传机制,当客户端的TCP未收到目的主机的确认报文段或者发送时间超时的时候,TCP会重新发送报文段,而中间的等待过程可能会很漫长。TCP还有一个拥塞控制机制,当源和目的主机之间的一条或多条链路变得极度拥塞的时候,TCP就会遏制运输层TCP发送方,来解决拥塞情况.
  • 不需要建立连接
    UDP发送数据的时候不经过任何准备,直接将数据打包进报文段然后传递给网络层即可,而TCP需要和目的主机间建立连接,即三次握手,UDP少去了建立连接的时延,这可能是DNS协议运行在UDP而不是运行在TCP上的主要原因.
  • 无连接状态
    TCP在端系统中需要维护连接状态,因为TCP需要提供可靠的数据传输服务和拥塞控制服务,而UDP不需要维护连接状态,所以说,有些应用程序使用UDP一般能支持更多的在线用户.
  • 分组首部开销小
    TCP每个报文段含有20字节的首部开销,而UDP只有8字节的首部开销.

UDP报文段结构

UDP报文段结构
UDP首部包括源端口号、目的端口号、长度、检验和.

  • 长度
    指示了在UDP报文段(包括UDP首部和数据)中的字节数.
  • 检验和
    接收方通过检查检验和来检查该报文段是否出现差错.

面向连接的服务TCP

TCP是面向连接的协议,在两个进程之间要发生数据传输的时候,需要在两个进程之间建立连接,也就是先互相握手,互相发送一些特殊的预备报文段,以建立确保数据传输的参数.

TCP的套接字

一个TCP套接字由一个四元组来进行标识,该四元组包括源IP地址、源端口号、目的IP地址、目的端口号.

TCP的特点

  • 全双工服务
    当A和B之间建立了TCP连接,那么 应用层数据可以在A流向B的同时,从B流向A.
  • 点对点
    TCP只允许单个发送方和单个接收方之间连接,在一次发送操作中,一个发送方不能将数据发送给多个接收方.

发送缓存和接收缓存

客户进程通过套接字传递数据流,数据一旦通过套接字,它就由运行中的TCP控制了,TCP将这些数据引导到该连接的发送缓存中,发送缓存是三次握手初期设置的缓存之一.当TCP在另一端接受到一个报文段后,该报文段的数据就被放在该TCP连接的接收缓存中,TCP可从缓存中取出并放入报文段中的数据数量受限于最大报文段长度(MSS).
TCP的每一端都有各自的发送缓存和接收缓存

TCP连接的组成

  • 一台主机上的缓存
  • 变量和
  • 进程连接的套接字
  • 另外一台主机的前三种

TCP报文段结构

TCP报文段结构

  • 源端口号和目的端口号
    用于多路复用/分解来自或送到上层应用的数据.
  • 序号和确认号(32bit)
    TCP把数据看成无结构的、有序的字节流。因为序号是建立在传送的字节流上,而不是建立在传送的报文段的序列之上,一个报文段的序号 因此是该报文段首字节的字节流编号。主机A填充进报文段的确认号是主机A期望从主机B收到的下一字节的序号.
    • 累计确认
      当主机A已经接收到来自主机B的包含字节0~226和字节463~1000的报文段,没有接收到字节227~462的报文段,因此,A到B的下一个报文段的确认号字段包括227,因为TCP只确认该流中第一个丢失字节为止的字节.
  • 接受窗口(16bit)
    用于流量控制.
  • 首部长度(4bit)
    指示了以32比特的子为单位的TCP首部长度,由于TCP选项字段的原因,TCP首部的长度是可变的.
  • 可选和变长的选项字段
    用于发送方和接收方协商最大报文段长度时,或在高速网络环境下用作窗口调节因子时使用.
  • 标志字段(6bit)

TCP三次握手

客户TCP状态:初始为CLOSED(关闭)

  • 第一步,客户端的TCP首先向服务器端的TCP发送一个特殊的TCP报文段,该报文段不含应用层数据, 报文段首部中的一个标志位(SYN比特)被置为1,因此,该报文段被称为SYN报文段.另外,客户会随机选择一个初始序号(client_isn),并将此编号放置于该起始的TCP SYN报文段的序号字段中。该报文段会被封装在一个IP数据中,并发送给服务器,完成后客户TCP状态为SYN_SEND.
  • 第二步,一旦包含TCP SYN报文段的IP数据报到达服务器主机,服务器会从该数据报中提取出TCP SYN数据报,为该TCP连接分配TCP缓存和变量,并向客户发送允许连接的报文段.这个报文段也不包含应用层数据.但是该报文段却包含3个重要的信息:1.SYN比特被置为1,2.该TCP报文段的首部确认号字段被置为client_isn + 1 3.服务器选择自己的初始序号server_isn,并将其放置到TCP报文段首部的序号字段中.该允许连接的报文段通常被称为SYNACK报文段,完成后客户TCP状态仍为SYN_SEND.
  • 第三步,在收到SYNACK报文段之后,客户也要给该连接分配缓存和变量。客户主机向服务器发送另一个报文段,对服务器的允许连接报文段进行确认,该客户通过将值server_isn + 1放置到TCP报文段首部的确认字段中来完成。因为连接已经建立,所以说SYN比特被置为0,这次可以在报文段中携带客户到服务器的数据,完成后客户TCP状态为ESTABLISHED(已建立).

TCP四次挥手

参与TCP连接中的两个进程任何一个都能关闭连接,当连接结束后,主机中的缓存和变量将被释放.
以客户要关闭连接为例

  • 第一步
    客户应用进程发出一个关闭连接命令,这会引起客户TCP向服务器进程发送一个特殊报文段,这个特殊报文段首部中的一个标志位,即FIN比特被设置为1,客户TCP状态处于FIN_WAIT_1状态.
  • 第二步
    当服务器收到该报文段的后,就向发送发送一个确认报文段,客户TCP收到确认报文段之后,客户TCP状态处于FIN_WAIT_2状态.
  • 第三步
    服务器 发送它自己的终止报文段,其FIN比特被置为1
  • 第四步
    客户对服务器的终止报文段进行确认,客户TCP状态处于TIME_WAIT状态。

客户TCP状态序列

客户TCP状态序列

服务器TCP状态序列

服务器TCP状态序列

TCP&UDP问题解读

以下问题解答均为个人理解,如有错误,请指出.

Q:描述应用程序开发者为什么可能选择在UDP上运行应用程序而不是在TCP上运行的原因。

答案就是UDP的优点,可以总结概括一下:

  • 关于何时、发送什么数据的应用层控制更为精细。
  • 无需连接建立。TCP连接需要三次握手,而UDP则不需要,所以可以省去握手阶段的时间。
  • 无连接状态。TCP需要在端系统中维护连接的状态,包括接收和发送缓存、拥塞控制参数以及序号与确认号的参数。
  • 分组首部开销小。每个TCP的报文段首部都有20字节的首部开销,而UDP仅有8字节的开销。

Q:在今天的因特网中,为什么语音和图像流量常常是经过TCP而不是经过UDP发送。(提示:我们寻找的答案与TCP的拥塞控制机制没有关系。)

如果第一眼看到这个,一般直接就会说出TCP的可靠数据传输服务和拥塞控制机制,但是题目明确指出和TCP的拥塞控制机制没有关系,所以说,这就需要思考了.
这是我在书上看到的一个题目,书本的作者是这样回答的:

Since most firewalls are configured to block UDP traffic, using TCP for video andvoice traffic lets the traffic though the firewalls.

翻译一下也就是大概意思就是:因为大多数端系统的防火墙会阻止UDP流量,因此需要使用TCP发送。(英语渣在此 = =)

Q:运行在UDP上的应用程序可以获得可靠地数据传输服务吗?如何实现?

可能可以得到,可以在应用程序中建立可靠地传输机制,例如重传机制.

Q:为什么是三次握手?换成两次可以吗?

假设现在只有前两次握手,没有第三次握手,客户向服务器发送一个SYN报文段,请求建立连接,但是因为网络原因延迟了,服务器未能在一定时间内收到报文段,因为TCP的重传机制,所以客户会再次发送SYN报文段,且与第一个报文段的序列号是一样的,这个报文段可以到达服务器,服务器接受,连接建立。在通信结束后,连接断开,但是第一次的SYN报文段到达了,服务器以为客户要再次建立连接,所以就接受,连接建立,但是客户已经不会使用这条连接,那么不会通过这条连接向服务器发送数据,那么这条连接就是一个空的连接,浪费了资源.
使用三次握手后,在第三次握手的时候,当服务器收到客户的确认之后,才会建立连接,如果没有收到确认,是不会建立连接的.
总结来说就是:三次握手的目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误.

Q:三次握手过程中的第三次握手的ACK丢失会怎么办?

在第二次握手之后,服务器会等待客户发送过来的ACK,如果没有收到,那么会重新发送SYN + ACK,一般会重复几次,如果还没有收到,那么服务器会关闭这次连接,即进入CLOSED状态,但是客户会以为连接已经建立,会向服务器发送数据,这时服务器会发送RST包来告诉客户重新建立连接(从第一次握手开始)。

Q:四次挥手过程中第四次挥手的ACK丢失会怎么办?

在第三次挥手中,客户对服务器的终止报文段进行确认,并发送ACK,此时客户进入TIME_WAIT状态,如果ACK丢失,服务器就会重新发送第三步的终止报文段,来使客户的计时器重置,再次发送ACK,但是,如果服务器重发的终止报文段未能在客户的计时器销毁之前到达客户,那么客户会进入CLOSED状态,服务器收不到ACK确认报文段,那么本次关闭不会成功.

参考文献

  • 计算机网络自顶向下 第六版
1 0
原创粉丝点击