【UNIX网络编程】传输层:TCP、UDP跟SCTP
【UNIX网络编程】传输层:TCP、UDP和SCTP
UDP(User Datagram Protocol,用户数据报协议):
- 不可靠的:不保证UDP数据报会到达其最终目的地,不保证各个数据报的先后顺序跨网络后保持不变,不保证每个数据报只到达一次
- 数据报模式:每一个UDP数据报都有一个长度,如果一个数据报正确到达目的地,那么该数据报长度将随数据一道床底给接收端应用进程(有记录边界,不同于TCP)
- 无连接的:UDP客户与服务器不必存在任何长期的关系,一个UDP客户可以创建一个套接字发送一个数据报给一个服务器,然后立即用同一个套接字发送另一个数据报给另一个服务器,同理,UDP服务器也可以用同一个套接字接收不同客户的数据报
TCP(Transmission Control Protocol,传输控制协议):
- 面向连接的:TCP客户先与某个给定服务器建立一个连接,再跨这个连接与那个服务器交换数据,然后终止这个连接。
- 可靠的:TCP向另一端发送数据时,要求对端返回一个确认。如果没有收到确认,TCP就自动重传数据并等待更长时间。在数次重传失败之后,TCP才放弃(尝试发送的总时间依赖于具体实现)。TCP提供的是数据的可靠递送或故障的可靠通知(通过放弃重传并中断连接)。
- 字节流模式:没有任何记录边界,因此不确定一次返回了多少数据,所以在TCP套接字读取数据时,需要将读取函数写在某个循环中
- TCP的一些特点:
- TCP含有用于动态估算客户和服务器之间的往返时间(round-trip time , RTT)的算法,以便它知道等待一个确认需要多少时间。RTT受网络流通各种变化因素影响,TCP还持续估算一个给定连接的RTT。
- TCP通过给其中每个字节关联一个序列号对所发送的数据进行排序(sequencing)。假设一个2048字节的数据分为2个“分节”(分节是TCP传递给IP的数据单元)发送,如果这些分节不是顺序到达,或者某个分节由于网络拥挤导致重复数据,接收端TCP将先根据它们的序列号重新排序,并丢弃重复数据。(UDP不提供可靠性,所以没有确认、序列号、RTT估算、超时和重传等机制,但是UDP应用必须处理颠倒、重复等所有这些异常情况)
- TCP提供流量控制(flow control),TCP总是告知对端在任何时刻它一次能够从对端接收多少字节的数据,这称为通告窗口(advertised window)。该窗口指出接收缓冲区中当前可用的空间量,从而确保发送端发送的数据不会使接收缓冲区溢出。(当应用不从缓冲区读取数据的时候,窗口大小可能减小到0)。(同样地,UDP不提供流量控制)
- TCP连接是全双工的(full-duplex),在一个给定的连接上,应用可以在任何时刻在进出两个方向上既发送数据又接收数据。因此,TCP必须为每个数据流方向跟踪诸如序列号和通告窗口大小等状态信息。
SCTP(Stream Control Transmission Protocol,流控制传输协议):SCTP在客户和服务器之间提供关联(association),并像TCP那样给应用提供可靠性、排序、流量控制以及全双工的数据传送。此处注意“关联”和“连接”,“连接”只涉及两个IP地址之间的通信,“关联”指代两个系统之间的一次通信,SCTP支持多宿而涉及不止两个地址(单个SCTP断电能够支持多个IP地址,如果它的某个网络或某个跨越因特网的桐庐发送故障,SCTP就可以通过切换到使用已经与该关联相关的另一个地址来规避所发生的故障)。SCTP是面向信息的(message-oriented)。它提供各个记录的按序递送服务,与UDP一样,由发送端写入的每条记录的长度随数据一道传递给接收端应用。SCTP能够在所连接的端点之间提供多个流,每个流各自可靠地按序递送消息。一个流上某个消息的丢失不会阻塞同一关联其他流上消息的投递。TCP而言,在单一字节流中任何位置的字节丢失都将阻塞该连接上其后所有数据的递送,直到该丢失被修复为止。
TCP的建立和终止
- 三次握手(需要3个分节的交换才可以完成TCP的连接)的过程描述:
- 服务器必须准备好接收外来的连接,这通过调用socket,bind和listen这3个函数来完成,我们称之为被动打开(passive open) -> 这里还没有开始握手
- 客户通过调用connect发起主动打开(active open)。这导致客户TCP发送一个SYN(同步)分节,它告诉服务器客户将在(待建立的)连接中发送的数据的初始序列号。通常SYN分节不携带数据,其所在IP数据报只含有一个IP首部、一个TCP首部及可能有的TCP选项
- 服务器必须确认(ACK)客户的SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器在单个字节中发送SYN和对客户SYN的ACK(确认)
- 客户必须确认服务器的SYN
- 常用的TCP选项
- MSS选项:发送SYN的TCP异端使用本选项通告对端它的“最大分节大小”(maximum segment size),也就是它在本连接的每个TCP分节中愿意接收的最大数据量。发送端TCP使用接收端的MSS值作为所发送分节的最大大小。 TCP_MAXSEG
- 窗口规模选项:原始的TCP连接任何一端能够通告对端的最大窗口大小是65535,因为在TCP首部中相应的字段占16位。随着因特网的发展,要求有更大的窗口以获得尽可能大的吞吐量,这个新选项指定TCP首部中的通告窗口必须扩大(左移0到14位),因此所提供的最大窗口接近1G。在TCP连接上使用窗口规模的前提是它的两个端系统必须都支持这个选项。 SO_RCVBUF
- 时间戳选项:用于防止失而复现的分组可能造成的数据损坏。
- TCP连接终止(四次挥手,终止一个连接需要4个分节):
- 某个应用进程首先调用close,我们称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。(调用close或无论是否自愿地终止进程时,都会导致TCP发送FIN)
- 接收到这个FIN的对端执行“被动关闭”(passive close)。这个FIN由TCP确认。它的接收也作为一个文件结束符(EOF)传递给接收端应用进程,因为FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。(相当于接收到FIN的同时也接到了一个EOF)
- (接第2步,还是在“被动关闭”端)一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN
- 接收这个最终FIN的原发送端TCP(“主动关闭”端)确认这个FIN
- TCP状态转换图(待写 page. 34)