TCP 连接
TCP被称为是面向连接的 (connection - oriented)
这是因为在一个应用进程可以开始向另一个应用进程发送数据之前,这两个进程必须先相互“ 握手”
即它们必须相互发送某些预备报文段,以建立确保数据传输的参数
作为TCP连接建立的一部分, 连接的双方都将初始化与TCP连接相关的许多TCP状态变量
TCP 定义在 RFC 793、RFC 1122、RFC 1323、RFC 2018 以及 RFC 2581的标准文档中
TCP 起源
在20世纪70年代早期,分组交换网开始飞速增长,而因特网的前身 ARPAnet 也只是当时众多分组交换网中的一个。这些网络都有它们各自的协议。
Vinton Cerf 和 Robert Kahn 这两个研究人员认识到互联这些网络的重要性,发明了沟通网络的TCP/IP协议
该协议代表传输控制协议/网际协议 (Transmission Control Protocol/ Intermet Protocol)
虽然 Cerf 和 Kahn 开始时把该协议看成是单一的实体,但是后来将它分成单独运行的两个部分:TCP和IP。
Cerf 和 Kahn 在1974 年5月的《 IEEE Transactions on Communications Technology》杂志上发表了一篇关于TCP/IP 的论文。
V. Cerf and R. Kahn, “A Protocol for Packet Network Intercommunication,” in IEEE Transactions on Communications, vol. 22, no. 5, pp. 637-648, May 1974, doi: 10.1109/TCOM.1974.1092259.
A Protocol for Packet Network Intercommunication.pdf
TCP/IP协议是当今因特网的支柱性协议,但它的发明先于PC、工作站、智能手机和平板电脑,先于以太网、DSL、WiFi 和其他接入网技术的激增,先于Web、社交媒体和流式视频等。
Cerf 和 Kahn看到了对于联网协议的需求,一方面为行将定义的应用提供广泛的支持,另一方面允许任何主机与链路层协议互操作。
2004年,Cerf 和 Kahn由于“联网方面的开创性工作(包括因特网的基本通信协议TCP/IP的设计和实现)以及联网方面富有才能的领导”而获得ACM图灵奖,该奖项被认为是“计算机界的诺贝尔奖”
连接原理
这种 TCP“连接”不是一条像在电路交换网络中的端到端TDM或FDM电路,也不是条虚电路
因为其连接状态完全保留在两个端系统中
由于TCP协议只在端系统中运行,而不在中间的网络元素( 路由器和链路层交换机)中运行,所以中间的
网络元素不会维持TCP连接状态。
事实上,中间路由器对TCP连接完全视而不见,它们看到的是数据报,而不是连接。
连接建立
TCP连接提供的是全双工服务(full-duplex service)
如果一台主机上的进程 A 与另一台主机上的进程 B 存在一条TCP连接,那么应用层数据就可在从进程 B 流向进程 A 的同时,也从进程 A 流向进程 B。
TCP连接也总是点对点(point-to-poin)的, 即在单个发送方与单个接收方之间的连接。所谓“多播”,即在一次发送操作中,从一个发送方将数据传送给多个接收方,对TCP来说这是不可能的。
对于TCP而言,两台主机是一对。
现在来看看TCP连接是怎样建立的。假设运行在某台主机上的一个进程想与另一台主机上的一个进程建立一条连接。
发起连接的这个进程被称为客户进程,而另一个进程被称为服务器进程。
该客户应用进程首先要通知客户运输层,它想与服务器上的一个进程建立一条连接。
一个Python客户程序通过发出下面的命令来实现此目的。
clientSocket.connect((serverName, serverPort))
其中srverName是服务器的名字,severPort 标识了服务器上的进程。
客户上的 TCP 便开始与服务器上的 TCP 建立一条 TCP 连接。
客户首先发送一个特殊的 TCP 报文段,服务器用另一个特殊的TCP报文段来响应,最后,客户再用第三个特殊报文段作为响应。
前两个报文段不承载“有效载荷”,也就是不包含应用层数据;而第三个报文段可以承载有效载荷。
由于在这两台主机之间发送了3个报文段,所以这种连接建立过程常被称为三次握手 (three- way handshake)。
数据传输
一旦建立起一条TCP连接,两个应用进程之间就可以相互发送数据了。
考虑一下从客户进程向服务器进程发送数据的情况。
客户进程通过套接字传递数据流。数据一旦通过该门,它就由客户中运行的TCP控制了。
TCP将这些数据引导到该连接的发送缓存(send buffer)里,发送缓存是在三次握手初期设置的缓存之一。
接下来TCP就会不时从发送缓存里取出一块数据。
有趣的是,在TCP规范 [RFC 793] 中却没提及 TCP 应何时实际发送缓存里的数据,只是描述为“TCP应该在它方便的时候以报文段的形式发送数据”
TCP 可从缓存中取出并放入报文段中的数据数量受限于最大报文段长度 ( Maximum Segment Size, MSS)
MSS 通常根据最初确定的由本地发送主机发送的最大链路层帧长度( 即所谓的最大传输单元( Maximum Transmission Unit, MTU))来设置。
设置该 MSS 要保证一个 TCP 报文段 (当封装在一个IP数据报中) 加上TCP/IP首部长度 (通常40字节) 将适合单个链路层帧。
以太网和 PPP 链路层协议都具有1500字节的 MTU,因此 MSS 的典型值为1460字节。
已经提出了多种发现路径 MTU 的方法,并基于路径 MTU 值设置MSS (路径MTTU是指能在从源到目的地的所有链路上发送的最大链路层帧 [RFC 1191])。
注意到 MSS 是指在报文段里应用层数据的最大长度,而不是指包括TCP首部的TCP报文段的最大长度。
TCP 为每块客户数据配上一个 TCP 首部,从而形成多个 TCP 报文段 (TCP segment )。
这些报文段被下传给网络层,网络层将其分别封装在网络层IP数据报中。
然后这些 IP 数据报被发送到网络中。当TCP在另端接收到一个报文段后,该报文段的数据就被放入该 TCP 连接的接收缓存中。
应用程序从此缓存中读取数据流。TCP连接的每一端都有各自的发送缓存和接收缓存。
TCP连接的组成包括:一台主机上的缓存、变量和与进程连接的套接字,以及另一台主机上的另一组缓存、变量和与进程连接的套接字。
在这两台主机之间的网络元素 (路由器、交换机和中继器) 中,没有为该连接分配任何缓存和变量。