TCP : 传输控制协议
TCP是一个面向连接的协议,为用户进程提供可靠的全双工字节流。TCP套接字时一个流套接字(stream socket)。TCP关心确认,超时和重传之类的细节。
TCP提供客户端与服务器之间的连接。
TCP提供流量控制,TCP总是告知对端在任何时刻它一次能够从对端接收多少字节的数据,这称为通告窗口。通告窗口指出接收缓冲区中当前可用的空间量,从而确保发送端发送的数据不会使接收缓冲区溢出。
TCP连接是全双工的,这意味着在一个给定的连接上应用可以在任何时刻在进出两个方向上既发送数据又接收数据。
UDP:用户数据报协议
UDP是一个无连接协议,UDP套接字是一种数据报套接字。
应用进程往一个UDP套接字写入一个消息,该消息随后被封装到一个UDP数据报,该UDP数据报进而又被封装到一个IP数据报,然后发送到目的地。
UDP不保证UDP数据报会到达其最终目的地,不保证各个数据报的先后顺序跨网络后保持不变,也不保证每个数据报只到达一次。
UDP提供无连接服务,因为UDP客户和服务器之间不必存在长期的关系。
TCP连接建立
三次握手
建议一个TCP连接时会发生下述情形:
1.服务器必须准备好接受外来的连接。通过调用socket,bind和listen函数完成。称之为被动打开。
2.客户通过调用connect发起主动打开。导致客户TCP发送一个SYN(同步)分节,告诉服务器将在连接中发送的数据的初始序列号。
3.服务器必须确认(ACK)客户的SYN,同时自己也发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器在单个分节中发送SYN和对客户SYN的ACK(确认)。
4.客户必须确认服务器的SYN。
这种交换至少需要3个分组,因此称之为TCP的三路握手。
TCP连接终止
四次挥手
终止一个连接需4个分节:
1.某个应用进程首先调用close,称该端执行主动关闭。该端的TCP发送一个FIN分节,表示数据发送完毕。
2.接收到这个FIN的对端执行被动关闭。这个FIN由TCP确认,作为一个文件结束符传递给接收端应用进程。
3.接收到这个文件结束符的应用程序将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。
4.接收到这个最终FIN的原发送端TCP确认这个FIN。
每个方向都需要一个FIN和一个ACK,所以需要4个分节。
当一个UNIX进程无论自愿的(exit或return)还是非自愿的(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭。
观察分组
一个完整的TCP连接所发生的实际分组交换情况,包括连接建立,数据传送和连接终止3个阶段。
TIME-WAIT状态
重温四次握手过程:
假设A是服务器端,主机A向B发送FIN信息相当于在服务器端控制台输入CTRL+C。
套接字经过四次握手过程后并非立即删除,而是要经过一段时间的Time-wait状态。套接字处在Time-wait状态时,相应端口是正在使用的状态。因此bind()调用过程中当然会发生错误。
先端开连接的(先发送FIN消息)的主机才经过Time-wait状态。
提示:
不管是服务器端还是客户端都会有Time-wait状态。先端开连接的套接字必然会经过Time-wait过程。因为客户端套接字的端口号是任意指定的,与服务器端不同,客户端每次运行程序时都会动态分配端口号,因此无需过多关注Time-wait过程 (所以上例中从客户端结束,再运行服务器端分配同样端口号不会bind() error!)
Time-wait状态的作用:
四次握手过程中, 假设A向B发送完最后一条ACK消息后立即消除套接字:
若主机A向主机B传输最后一条ACK消息(SEQ 7501,ACK 5001)在传递途中丢失,未能传给主机B。主机B没收到确认信号,会认为之前发送的FIN消息(SEQ 7501, ACK 5001)未能抵达主机A,继而重传。若此时A已是完全终止的状态,则主机B永远无法收到从主机A最后传来的ACK消息。相反,若主机A的套接字处于Time-wait状态,则会向主机B重传最后的ACK消息。
基于这些考虑,先传输FIN消息的主机应经过Time-wait过程。
端口号
TCP和UDP协议都使用16位整数的端口号来区分不同进程。
端口号被分为以下3端:
1.端口0~1023,这些端口由IANA分配和控制。是保留端口,这些端口只能赋予特权用户进程的套接字。
2.已登记的端口为1024~49151,这些端口不受IANA控制,不过由IANA登记并提供它们的使用情况。可能的话,相同端口号也分配给TCP和UDP同一给定服务。
3.49152~65535是动态或私用端口。这些就是临时端口,通常由传输层协议自动赋予客户。
TCP输出
TCP提取套接字缓冲区中的数据并把它们发送到对端TCP。本端TCP以MSS大小或更小的块把数据传递给IP,同时每个数据报岸上TCP首部以构成TCP分节,其中MSS或是由对端通告的值。
UDP输出
这一端的UDP简单给来自用户的数据报安上它的8字节的首部以构成UDP数据报,然后传递给IP。