传输层:TCP、UDP
UDP是一个简单的、不可靠的数据报协议。用户数据报协议(User Datagram Protocal)是一个无连接协议。UDP套接字是一种数据包套接字。UDP数据报不能保证最终达到他们的目的。
UDP是一个简单的传输层协议。应用进程往一个UDP套接字写入一个消息,该消息随后被封装到一个UDP数据包,数据包进而又被封装到一个IP数据包,然后发送到目的地。UDP不保证UDP数据包会到达其最终目的地,不保证各个数据包的先后顺序跨网络后保持不变,也不能保证每个数据包只到达一次。
UDP进行网络编程所遇到的问题是它缺乏可靠性,如果一个数据到达了其最终目的地,但是校验和检测发现有错误,或者该数据在网络传输途中被丢弃了,它就无法投递给UDP套接字,也不会被源端自动重传。
TCP是一个复杂、可靠的字节流协议。传输控制协议(Transmission Control Proctocol)是一个面向连接的协议,为用户进程提供可靠的全双工字节流。TCP套接字是一种流套接字。TCP关心确认、超时和重传之类的细节。
由TCP向应用进程提供的服务不同于由UDP提供的服务。
首先,TCP提供客户端与服务器之间的连接。TCP客户先给某个给定服务器建立一个连接,在跨该连接与那个服务器交换数据,然后终止这个连接。
其次,TCP还提供了可靠性。当TCP向另一端发送数据时,它要求对端返回一个确认。如果没有收到确认,TCP就重传数据并等待更长时间。在数次重传失败后,TCP才放弃,如此在尝试发送数据上所花的总时间一般为4-10分钟。TCP含有用于动态估算客户和服务器之间往返时间(round-trip time,RTT)的算法,以便它知道等待一个确认需要多少时间。TCP通过给其中每个字节关联一个***对所发送的数据进行排序(Sequencing)。例如,假设一个应用写2048字节到一个TCP套接字,导致TCP发送2个字节;第一个分节所含数据的***为1-1024,第二个分节所含数据序号为1025-2048。如果这些分节非顺序到达,接受端TCP将先根据它们的***重新排序,再把结果传递给接受应用。如果接收端TCP接受来自对端的重复数据(比如说对端认为一个分节已经丢失因此重传,而这个分节并没有真正丢失,只是网络过于拥挤),它可以(根据***)判定是重复的,从而丢失重复数据。
再次,TCP提供流量控制。TCP总是告知对端在任何时刻它一次能从对端接收多少字节的数据,这称为通告窗口。在任何时刻,该窗口指出接收缓冲区中当前可用的空间量,从而确保发送端的数据不会使接收缓冲区溢出。该窗口时刻动态变化:当接收到来自发送端的数据时,窗口大小就减小,但是当接收端应用从缓冲区中读取数据时,窗口大小就增大。
最后,TCP连接是全双工的(full-duplex)。这意味着在一个给定的连接上应用可以在任何时刻在进出两个方向上既发送数据有接收数据。因此,TCP必须为每个数据流方向跟踪诸如***和通告窗口大小等状态信息。
TCP连接的建立和终止
TCP的三路握手(建立连接)
1.服务器必须准备好接收外来的连接,我们称之为被动打开。
2.客户端通过调用Connect发起主动打开。客户端TCP发送一个SYN(同步)分节,它告诉服务器客户端将在(待建立的)连接中发送的数据的初始***。通常SYN分节不携带数据,其所在IP数据包只含有一个IP首部、一个TCP首部及可能有的TCP选项
3.服务器必须确认(ACK)客户端SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的数据初始***。
4.客户端必须确认服务器的SYN
TCP连接终止
TCP建立一个连接需3个分节,终止一个连接则需4个分节。
1.某个应用进程首先调用Close,该端执行主动关闭。该端的TCP于是发送一个FIN分节,表示数据发送完毕。
2.接收到这个FIN的对端执行被动关闭。这个FIN由TCP确认。它的接收也作为一个文件结束符传递给接受端应用程序(放在已排队等候该应用进程接受的任何其他数据之后),因为FIN的接收意味着接收端应用进程在相应连接上在无额外数据可接收。
3.一段时间后,接收到这个文件结束符的应用程序调用close关闭它的套接字。这导致它的TCP也发送一个FIN.
4.接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN