第2章 传输层:TCP、UDP和SCTP

2023-10-19 12:32
文章标签 udp tcp 传输层 sctp

本文主要是介绍第2章 传输层:TCP、UDP和SCTP,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2.6  TCP连接的建立和终止

 为帮助大家理解connect、accept和close函数并使用netstat调试TCP应用程序,我们必须了解TCP连接如何建立和终止以及TCP的状态转换图。

 

三路握手

    下述步骤建立一个TCP连接:
    1.服务器必须准备好接受外来的连接。这通过调用socket、bind和listen函数来完成,称为被动打开(passive open)。
  2.客户通过调用connect进行主动打开(active open)。这引起客户TCP发送一个SYN( 表示同步)分节,它告诉服务器客户将在(待建立的)连接中发送的数据的初始序列号。一般情况下SYN分节不携带数据,它只含有一个IP头部、一个TCP头部及可能有的TCP选项。
    3.服务器必须确认客户的SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器以单个分节向客户发送SYN和对客户SYN的ACK(表示确认)。
    4. 客户必须确认服务器的SYN。连接建立过程至少需要交换三个分组,因此称之为TCP的三路握手(threeway handshake)。图2.2中展示了这三个分节。


图2.2TCP的三路握手


    图2.2给出的客户的初始序列号为J,而服务器的初始序列号为K。在ACK里的确认号为发送这个ACK的一端所期待的对端的下一个序列号。因为SYN只占一个字节的序列号空间,所以每一个SYN的ACK中的确认号都是相应的初始序列号加1。类似地,每一个FIN(表示结束)的 ACK中的确认号为FIN的序列号加1。

    建立TCP连接的日常系统类比是电话系统[Nemeth 1997]。socket函数等同于有电话可用。bind用于告诉其他人你的电话号码,让他们可以向你打电话。listen是打开电话振铃,它使你可以听到一个外来的电话。connect要求你知道对方的电话号码并拨打它。accept是被呼叫回电话。从accept返回客户的标识(即客户的IP地址和端口号)类似于让电话机的呼叫者ID 功能部件显示打电话人的电话号码。然而有点不同的地方是:从accept返回客户的标识是在建立连接以后,而呼叫者ID功能部件显示打电话人的电话号码是在我们选择接或不接电话之前。如果使用域名系统(第11章),那么提供了一种类似于电话簿的服务。getaddrinfo类似于在电话簿查找个人的电话号码。
getnameinfo则类似于有一本按照电话号码而不是用户名排序的电话簿。

   
TCP选项

    每一个SYN可以含有若干个TCP选项。通常使用的选项有:
    ·MSS选项。TCP发送的SYN中带有这个选项是通知对端它的最大分节大小MSS(maximum segment size),即它能接受的每个TCP分节中的最大数据量。发送端TCP使用接收端的MSS 值作为所发送分节的最大大小。我们会看到如何使用TCP_MAXSEG套接口选项获取与设置这个TCP选项(7.9节)。
    ·窗口规模选项。TCP两端能够通知对端的最大窗口大小是65535,因为TCP头部相应的字段只占16位。但是当今因特网上业已普及的高速连接(每秒45兆位或更快,见RFC1323 [Jacobson,Braden,and Borman 1992])或长延迟的路径(卫星链路)要求有更大的窗口以获得尽可能最大的吞吐量。这个新选项指定TCP头部的通告窗口必须扩大(即左移)的位数 (0~14),因此所提供的最大窗口几乎是1G字节(65535×214)。两个端系统必须都支持这个选项,否则不具备扩大窗口规模能力。在7.5节我们将看到套接口选项SO_RCVBUF如何影响该选项。

    为提供与不支持这个选项的较早实现间的互操作性,应用如下的规则。TCP可以作为主动打开的一部分内容随它的SYN发送该选项,但只有对端也随它的SYN发送该选项时,它才能扩大窗口的规模。类似地,服务器的TCP只有接收到随客户的SYN来的这个选项时,它才能发送该选项。本逻辑假定实现会忽略它们不理解的选项。这是要求的,而且相当普遍,然而不幸的是无法保证所有实现都是这样。

    ·时间戳选项。这个选项对高速连接是必要的,它可以防止由失而复得的分组可能造成的数据损坏。因为它是新选项,所以其处理类似于窗口规模选项。作为网络编程人员,对于这个选项我们没有必要担心。
    TCP的大多数实现都支持这些选项。其中后两个选项有时也称为“RFC 1323选项”,因为它们是在RFC1323[Jacobson,Braden,and Borman 1992]中说明的。它们也称为“长胖管道 ”选项,因为高带宽或长延迟的网络被称为“长胖管道(long fat pipe)”。TCPv1的第24章对这些新选项有详细的叙述。

TCP连接终止

    TCP建立一个连接需三个分节,终止一个连接则需四个分节。
    1.某个应用进程首先调用close,我们称这一端执行主动关闭(active close)。这一端的TCP于是发送一个FIN分节,表示数据发送完毕。
    2.接收到FIN的另一端执行被动关闭(passive close)。这个FIN由TCP确认。它的接 收也作为文件结束符传递给接收端应用进程(放在已排队等候该应用进程接收的任何其他数 据之后),因为FIN的接收意味着应用进程在相应连接上再也接收不到额外数据。
    3.一段时间后,接收到文件结束符的应用进程将调用close关闭它的套接口。这导致它的TCP也发送一个FIN。  4.接收到这个FIN的原发送端TCP(即执行主动关闭的那一端)对它进行确认。因为每个方向都需要有一个FIN和一个ACK,所以一般需要四个分节。我们使用限定词“一般 ”是因为:有时步骤1的FIN随数据一起发送;另外,执行被动关闭那一端的TCP在步骤2和3 发出的ACK与FIN也可以合并成一个分节。图2.3说明了这些分组的交换过程。
FIN占据1个字节的序列号空间,这与SYN相同。所以每个FIN的ACK确认号是这个FIN的序列号加1。


图2.3TCP连接关闭时的分组交换

    在步骤2与步骤3之间可以有从执行被动关闭端到执行主动关闭端的数据流。这称为半关闭(h alfclose),我们将在6.6节随shutdown函数再详细介绍。套接口关闭时,每一端TCP都要发送一个FIN。这种情况在应用进程调用close时会发生,然而在进程终止时,所有打开的描述字将自愿(调用exit或从main函数返回)或不自愿(进程收到一个终止本进程的信号)地关闭,此时仍然打开的TCP连接上也会发出一个FIN。
    图2.3指出客户执行主动关闭,然而不管是客户还是服务器都可以执行主动关闭。通常情况是客户执行主动关闭,但某些协议如HTTP(超文本传送协议)则是服务器执行主动关闭。 

TCP状态转换图

    TCP连接的建立和终止可以用状态转换图(state transition diagram)来说明,见图2.4。
    TCP为一个连接定义了11种状态,并且TCP规则规定如何基于当前状态及在该状态下所接收的分节从一个状态转换到另一个状态。举例来说,当应用进程在 CLOSED状态下执行一个主动打开时,TCP将发送一个SYN并从CLOSED状态转换成SYN_SENT状态。如果该TCP接着接收到一个捎带ACK的SYN,它将发送一个ACK并转换成ESTABLISHED状态。这个最终状态是绝大多数数据传送发生的状态。
    有两个外向箭头引出自ESTABLISHED状态的连接终止处理。如果应用进程在接收到文件结束符前调用close(主动关闭),则转换成FIN_WAIT_1状态。如果在ESTABLISHED状态下应用进程接收到FIN,则转换成CLOSE_WAIT态。  
    我们用实线表示客户的状态转换,虚线表示服务器的状态转换。注意我们没有提到的两个转换:一个为同时打开(当两端几乎同时发送SYN并且这两个SYN在网络中彼此交错时),另一个为同时关闭(当两端同时发送FIN时)。
TCPv1的第18章将讨论这两种情况,它们是可能发生的,不过非常罕见。
    展示状态转换图的理由之一是给出11种TCP状态的名称。netstat命令的输出包括这些状态,它是调试客户/服务器应用程序的有用的工具。在第5章中我们将使用netstat去监视这些状态。 

观察分组

    图2.5说明一个完整的TCP连接所发生的实际分组交换情况:建立连接、传送数据和终止连接。图中展示了每个端点所历经的TCP状态。


图 2.4  TCP状体转换图

    本例中客户通告的MSS(最大分节大小)值是536(表明该客户只实现了最小重组缓冲区大小),而服务器通告的MSS值为1460(以太网上IPv4的典型值)。不同方向的MSS可以不相同(见习题2.5)。
    一旦连接建立,客户就构造一个请求并发送给服务器。这里我们假设该请求适合于单个TCP分节(即请求大小小于服务器通告的1460字节的MSS)。服务器处理该请求并发送应答,我们假设应答也适合于单个分节(本例即小于536)。这两个数据分节在图中使用粗箭头表示。注意,服务器对客户请求的确认是伴随其应答发送的。这种做法称为捎带(piggybacking),它通常在服务器处理请求并产生应答的时间少于200毫秒时发生。如果服务器耗用更长时间,例如1秒钟,那么我们将看到先是确认后是应答。(TCP数据流机理在TCPv1的第19章和第20章中详细叙述)


图 2.5  TCP连接中的分组交换

    以后4个分节终止连接。注意:执行主动关闭的那一端(客户端)进入TIME_WAIT状态,我们将在下一节讨论这种情况。
    图2.5中值得注意的是,如果连接的整个目的仅仅是发送一个单一分节的请求和接收一个单一分节的应答,那么使用TCP有8个分节的额外开销。如果改用UDP,那么只需交换两个分组:请求和应答。然而从TCP切换到UDP将丧失TCP提供给应用进程的全部可靠性,迫使可靠服务的一大堆细节从传输层(TCP)转移到UDP应用进程。TCP提供的另一个重要特性即拥塞控制也得由UDP应用进程处理。尽管如此,许多网络应用还是使用UDP,因为它们需要交换的数据量较少,而UDP避免了TCP连接建立和终止的额外开销。 

这篇关于第2章 传输层:TCP、UDP和SCTP的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/239789

相关文章

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

【Go】go连接clickhouse使用TCP协议

离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么                      🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time""github.com/ClickHouse/clickhouse-go/v2")func main(

2024.9.8 TCP/IP协议学习笔记

1.所谓的层就是数据交换的深度,电脑点对点就是单层,物理层,加上集线器还是物理层,加上交换机就变成链路层了,有地址表,路由器就到了第三层网络层,每个端口都有一个mac地址 2.A 给 C 发数据包,怎么知道是否要通过路由器转发呢?答案:子网 3.将源 IP 与目的 IP 分别同这个子网掩码进行与运算****,相等则是在一个子网,不相等就是在不同子网 4.A 如何知道,哪个设备是路由器?答案:在 A

图解TCP三次握手|深度解析|为什么是三次

写在前面 这篇文章我们来讲解析 TCP三次握手。 TCP 报文段 传输控制块TCB:存储了每一个连接中的一些重要信息。比如TCP连接表,指向发送和接收缓冲的指针,指向重传队列的指针,当前的发送和接收序列等等。 我们再来看一下TCP报文段的组成结构 TCP 三次握手 过程 假设有一台客户端,B有一台服务器。最初两端的TCP进程都是处于CLOSED关闭状态,客户端A打开链接,服务器端

网络原理之TCP协议(万字详解!!!)

目录 前言 TCP协议段格式 TCP协议相关特性 1.确认应答 2.超时重传 3.连接管理(三次握手、四次挥手) 三次握手(建立TCP连接) 四次挥手(断开连接)  4.滑动窗口 5.流量控制 6.拥塞控制 7.延迟应答 8.捎带应答  9.基于字节流 10.异常情况的处理 小结  前言 在前面,我们已经讲解了有关UDP协议的相关知识,但是在传输层,还有

linux下TCP/IP实现简单聊天程序

可以在同一台电脑上运行,在一个终端上运行服务器端,在一个终端上运行客户端。 服务器端的IP地址要和本地的IP相同,并分配端口号,客户端的默认设置为本地,端口号自动分配。 服务器端: #include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.

JAVAEE初阶第七节(中)——物理原理与TCP_IP

系列文章目录 JAVAEE初阶第七节(中)——物理原理与TCP_IP 文章目录 系列文章目录JAVAEE初阶第七节(中)——物理原理与TCP_IP 一.应用层重点协议)1. DNS2 .NAT3. NAT IP转换过程 4 .NAPT5. NAT技术的缺陷6. HTTP/HTTPS7. 自定义协议 二. 传输层重点协议 1 .UDP协议 2.1.1 UDP协议端格式 2.1.2 UD

VC环境下window网络程序:UDP Socket程序

最近在学Windows网络编程,正好在做UDPsocket的程序,贴上来: 服务器框架函数:              socket();    bind();    recfrom();  sendto();  closesocket(); 客户机框架函数:            socket();      recfrom();  sendto();  closesocket();

深入理解TCP通信

这大概是自己博客上面第三次写TCP通信demo了,总是写同样的内容也不太好啊,不过每一次都比前一次进步一点。这次主要使用了VIM编辑工具、gdb调试、wireshirk、netstat查看网络状态。 参考《C++服务器视频教程》、《Unix网络编程》 一、VIM常用命令 vim server.cpp #打开一个文件:w 写入文件:wq 保存并退出:q! 不保存退出显示行号

9.7(UDP局域网多客户端聊天室)

服务器端 #include<myhead.h>#define SERIP "192.168.0.132"#define SERPORT 8888#define MAX 50//定义用户结构体typedef struct{struct sockaddr_in addr;int flag;}User;User users[MAX];//用户列表void add_user(struct s