赞
踩
目录
TCP协议是面向连接的,可靠的,基于字节流的传输层通信协议。
UDP协议是面向无连接,不可靠的,基于数据报的传输层通信协议。
所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口。我们可以将其理解为操作系统为了方便应用与TCP/IP协议交互而提出的接口。
UDP(User Datagram Protocol)用户数据报协议。其特点是简单,快速,不可靠。(可以理解为我就将数据打个包我就发到网上去了,反正我发了,寄没寄到不关我事)
TCP(Transmission Control Protocol)传输控制协议。其特点是较为复杂,相对较慢,可靠。(我们可以理解为打电话,先建立两者之间的连接,再进行通信)
上图是UDP的数据报的格式。
其中16位UDP长度表示整个数据报的长度(包括UDP首部和UDP数据)的最大长度。16位UDP校验和用来校验数据(使用特定的算法如CRC等),如果校验和出错,数据报就会被直接丢弃。我们发现UDP首部的的长度是定长的。
从发送和接收两个层面来看,如下图所示。
注意:由于UDP在发送的时候只需要发出去即可,所以没有发送缓冲区,但是UDP有接收缓冲区 。
TCP最重要的特点就是其可靠性。其可靠性体现在以下几个方面。
1.TCP尽最大可能将数据发给对方。
2.即使没有发送给对方,至少给上层的进程一个交代。
3.保证接收方收到的数据是有序的。
4.TCP可以保证不会收到错误的数据。
5.TCP可以根据接受能力和网络承载情况做了发送量控制。
上图是TCP协议段的格式。
我们可以看出其首部是变长的。其中4位首部长度存储的信息就是表示该TCP头部有多少个32位(4字节)。所以TCP头部最大的长度为15*4=60字节。
16位源端口号和16位目的端口号以及16位校验和不再介绍。
其他的字段大部分是用来实现其可靠性的。
确认(acknowledge)应答机制(顾名思义就是我先问你收到了没,你说受到了。这就是确认应答)
但是要是一下发很多数据,我该怎么分辨哪条是哪条呢?这就涉及到数据编号机制。数据编号机制对应用层做编号(不含报头)、每个字节占用一个序号。
在上面的TCP协议段的格式中32位编号(SN)就用来填写本次发送数据的编号。对于接收端,只需要知道序号和长度就可以得到每个数据的序号。而接收端需要通过序号表示哪些数据收到了,于是就需要用到了32位确认序号(ASN),其中填充的是我在ASN之前的序号都收到了(也可以理解为下次期望收到的序号)。
TCP将做数据传输的和做应答的进行了合并。只要协议段的格式图中ACK的值为1表明这个段具有确认功能。
但是如果对方没有应答怎么办呢?应该是有两种情况,第一种是数据丢失了,第二种是对方的应答丢失了。无论是哪种方法,都通过一种超时重传的机制来解决。就是我们设定一个时间,如果没有收到对方的应答,我们就重发这个数据。(超时时间的选定会动态的来计算)。
要是多次重发也没有收到对方的应答。此时会认为线路出现了问题(1.关闭连接2.给上层进程返回信息,Java中通过异常的方法3.发送一个reset)
这里提出一个问题,什么是连接呢?这里的连接并不是事实存在的物理上的连接,而是说只要针对每条线路。记录下相关信息以维护这种状态。我们就将这种状态抽象为”连接“。(发送缓冲区、接收缓冲区、SN、ASN,以及对于全局的Map<port,pid>)
接下来我们来讨论TCP的三个阶段
1.建立连接阶段(又称握手阶段)
2.正式通信阶段
3.断开阶段(又称挥手阶段)
握手阶段的目的有两个,一是确认对方在线,二是传递一些信息进行同步。
我们首先需要主动连接方发起同步请求,然后被动连接方确认应答。这样就表示主动连接方的信息可以被被动连接方收到。同样的,被动连接方也需要这样,整体如上图所示。然后就可以发现我们可以将2和3合并在一起(将ACK打开)。这样我们就得到了TCP在建立连接阶段的三次握手。如下图。同步请求的开关在上面的TCP协议段中SYN位。只需置于1,表示该数据为同步数据。
让我们从状态的角度来看看三次握手的过程。
此阶段就是双方就可以进行通信了,而且是全双工的。
标志位中有一个FIN就是用来标识断开连接的。断开阶段共有多种可能性如下所示
以上三种分别是三次挥手、四次挥手、同时挥手。基本上就是主动方发送FIN后变成FIN_WAIT_1状态。接收FIN后变成CLOSE_WAIT状态。主动方收到确认后变成FIN_WAIT_2状态,再收到来自被动方的FIN之后变成TIME_WAIT状态,被动方发送后变成LAST_ACK状态。被动方接收到主动方的ACK后变成CLOSED状态。
我们再看看两个小问题?
假设服务器上出现了大量的CLOSE_WAIT状态。这是由什么引起的?显然是主动关闭方要求关闭后被动关闭方没有关闭连接。可能是被动关闭方没有写close()方法。
注意:TCP提供了一个异常关闭连接的方法,就是标志位中的RST。
什么叫流量控制,就是根据对方的接受能力以及线路的承载能力来控制我们发送的数据的多少。下面我们探讨根据对方的接收能力来进行控制。我们怎样才能知道对反的接收能力呢?显然是对方发送给我们才能知道。TCP协议段的图中有一个16位窗口大小(接收窗口),该部分的数据就可以告诉我们目前的接收能力。流量控制时采用滑动窗口的机制,此处不再展开介绍。
至于拥塞控制,我们无法精确知道当前的网络状况,只能通过特定的算法来进行推算。
TCP协议段里面还有URG,没有解释说明,这个标志位和16位紧急指针配合使用。这个机制认为,这段数据中有部分数据是更加紧急的,16位紧急指针就是一个指向重要数据的偏移量。(但是我们为什么不使用另外一个TCP连接来传输紧急数据呢?所以这个设计被认为没有什么用)
PSH标志位:psh置为0的时候允许TCP把收到的数据暂存一段时间,当为1的时候就不允许。(然后发现大家都贪心的将这个置为1)
TCP协议是面向连接的,可靠的,基于字节流的传输层通信协议。UDP协议是面向无连接,不可靠的,基于数据报的传输层通信协议。网络编程时, 如何选择传输层的协议?一般情况我们都会选择TCP但是在特定的场合,如视频通话,直播等对可靠性没有要求或者对实时性有要求的场景会选择UDP。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。