您的位置:首页 > 理论基础 > 计算机网络

分析TCP/IP协议栈代码之TCP

2016-07-05 18:30 309 查看
1. TCP介绍

TCP与UDP都属于传输层,但是与UDP不同的是,TCP是面向连接的,可靠的传输协议。

ps:需要找几篇文章来看看两者的不同和各自的用武之地了,虽然对下面的代码分析之后对何为“面向连接”,何为“可靠”有一个具象的了解,但是不够全面和系统,比如何时采用TCP,何时采用UDP,效果如何,当然还得解释清楚其中的原因所在。

2.  TCP首部

TCP数据被封装在一个IP数据报中,如图17 - 1所示。



图17 - 2显示TCP首部的数据格式。如果不计任选字段,它通常是20个字节。



 每个TCP段都包含源端和目的端的端口号,用于寻找发端和收端应用进程。这两个值加上IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接。有时,一个IP地址和一个端口号也称为一个插口或套接字(socket) 。这个术语出现在最早的TCP规范(RFC793)中,后来它也作为表示伯克利版的编程接口 。插口对或套接字对(socket pair)(包含客户IP地址、客户端口号、服务器 IP地址和服务器端口号的四元组 )可唯一确定互联网络中每个TCP连接的双方。
序号用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节。如果将字节流看作在两个应用程序间的单向流动,则 TCP用序号对每个字节进行计数。序号是32 bit的无符号数,序号到达2^32-1后又从0开始。

在TCP首部中有6个标志比特(此处结合下面的状态变迁图是实现的关键之所在)。它们中的多个可同时被设置为 1。我们在这儿简单介绍它们的用法,在随后的章节中有更详细的介绍。

URG 紧急指针(urgent pointer)有效(见2 0 . 8节) 。
ACK 确认序号有效。
PSH 接收方应该尽快将这个报文段交给应用层。
RST 重建连接。
SYN 同步序号用来发起一个连接。这个标志和下一个标志将在第 18章介绍。
FIN 发端完成发送任务。

TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个 16bit字段,因而窗口大小最大为65535字节。在24 . 4节我们将看到新的窗口刻度选项,它允许这个值按比例变化以提供更大的窗口。
检验和覆盖了整个的TCP报文段:TCP首部和TCP数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。 TCP检验和的计算和UDP检验和的计算相似,使用如11 . 3节所述的一个伪首部。
只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。我们将在20 . 8节介绍它。
最常见的可选字段是最长报文大小,又称为 MSS (Maximum Segment Size)。每个连接方通常都在通信的第一个报文段(为建立连接而设置 SYN标志的那个段)中指明这个选项。它指明本端所能接收的最大长度的报文段。我们将在 18 . 4节更详细地介绍MSS选项,TCP的其他选项中的一些将在第24章中介绍。从图17 - 2中我们注意到TCP报文段中的数据部分是可选的。我们将在 18章中看到在一个连接建立和一个连接终止时,双方交换的报文段仅有
TCP首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

        小结:

        TCP提供了一种可靠的面向连接的字节流运输层服务。我们简单地介绍了 TCP首部中的各个字段,并在随后的几章里详细讨论它们。

        TCP将用户数据打包构成报文段;它发送数据后启动一个定时器;另一端对收到的数据进行确认,对失序的数据重新排序,丢弃重复数据; TCP提供端到端的流量控制,并计算和验证一个强制性的端到端检验和。

        许多流行的应用程序如Telnet、Rlogin、FTP和SMTP都使用TCP。

3. TCP连接的建立与终止

3.1 建立连接协议

请求端(通常称为客户)发送一个 SYN段指明客户打算连接的服务器的端口,以及初  
始序号(ISN,在这个例子中为1415531521) 。这个SYN段为报文段1。

服务器发回包含服务器的初始序号的SYN报文段(报文段2)作为应答。同时,将确认  
序号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号。

客户必须将确认序号设置为服务器的 ISN加1以对服务器的SYN报文段进行确认(报文  
段3) 。

    这三个报文段完成连接的建立。这个过程也称为三次握手( three-way handshake) 。

以下为WireShark的建立连接数据的抓包,其中HTTP为服务器端:

注意:这里PC端的默认MSS是1460(因为是以太网),而STM32端的MSS是1408,这个可以在程序里面修改。



3.2 连接终止协议

建立一个连接需要三次握手,而终止一个连接要经过 4次握手。如下图所示,过程与建立连接的三次握手过程类似。



4.  TCP的状态变迁图

ps:跟着箭头走就ok了,当然不会所有的状态变迁都实现,看具体协议栈的实现,下面的代码就只实现了其中的一部分。






ESTABLISHED状态是连接双方能够进行双向数据传递的状态。

注意:并不是所有的状态变迁都需要实现的,这取决于协议栈的具体实现,但是必须要有至少一条状态回路来保证数据的传输。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tcp