计算机网络 自顶向下方法(应用层)
WireShark 抓包指南: https://zhuanlan.zhihu.com/p/82498482
协议分层
协议规定了发送者、接收者和所有中间设备为了高效通信需要遵守的规则。
协议分层允许我们将一个复杂的任务分解成几个较小的、简单的任务。
协议分层的好处:
- 第一,它允许我们将服务从实现中分离出来。一层需要能够接收较低一层的一系列服务,同时向较高层提供服务,而我们不需要关心这一层是如何实现的。
- 第二,在通信过程中中间系统只需要一些层次而不是所有的层次,如果不使用协议分层,形成的中间系统就不得不像端系统一样复杂,这样会提高整个系统的造价。
TCP/IP 各层描述
应用层
应用层通信处于两个进程之间,是端到端的一种通信方式。常见的涉及到的协议包括: 超文本传输协议(HTTP,是访问万维网的载体);简单邮件传输协议(SMTP,是电子邮件服务的主要协议);文件传输协议(FTP);远程登陆(TELNET);安全外壳(SSH,用于访问远端的站点);简单的网络管理协议(SNMP);域名系统(DNS);因特网组管理协议(IGMP,用于管理一个组的成员资格);
传输层
传输层也是端到端的,主要负责从运行于应用层的程序得到信息,并将它投递到目的主机相应的应用程序。常见的协议包括:传输控制协议(TCP) 是面向连接的,提供流量控制(匹配源主机的发送速率与目的主机的接收速率,以防止目的主机溢出)、差错控制(保证数据段无差错到达目的地和重新发送受损的数据段)、拥塞控制(减少由于网络拥塞造成的数据段丢失);用户数据报协议(UDP),无连接但是是比较简单的协议,不提供流量控制、差错控制或者拥塞控制;流控制传输协议(SCTP),结合了TCP与UDP的优点。
UDP协议:
- UDP提供了无连接的、不可靠的数据包服务。无连接意味着两个交换报文的终端之间没有逻辑连接。每个报文都是独立的实体,它被封装在一个称为数据报的分组中。
- UDP常用在邮件发送、视频通信、多媒体应用等场景。
TCP协议:
- TCP提供面向连接的可靠字节流传输,TCP要求两个终端首先通过交换一些连接建立分组来建立一个逻辑连接,这个阶段设置了两个终端的某些参数,包括分组大小、用于保存数据直到整个报文全部到达缓冲区的大小等等。
SCTP协议:
- SCTP协议提供了两个协议组合的功能。类似于TCP,SCTP提供了面向连接的可靠服务,但是它不是面向字节流,它是像UDP一样面向报文的。除此之外,SCTP可以通过多媒体网络层连接提供多媒体流服务。
- SCTP协议通常适用于那些不但需要可靠性,而且即使网络层连接发生错误也需保持连接不断开的应用。
网络层
网络层也是端到端的,主要负责指挥分组选择合适的路由器并通过。这一层不能取消,因为路由器不需要应用层和传输层,分割任务允许我们在路由器上加载较少的协议。常见的协议包括:因特网协议(IP),IP负责从源主机把一个分组路由到目的主机,IP是一个无连接的协议,不提供流量控制、差错控制和拥塞控制服务。网络层也包括单播(一对一) 和多播 (一对多)路由协议,虽然这些协议不参与路由,但是它为路由器创建转发路由表,为转发处理提供帮助。
数据链路层
数据链路层是基于点到点的传输。它负责选择从主机到目的地之间最好的一条线路进行数据传输。这条链路可以是一个具有链路层交换机的有线局域网、一个无线局域网、一个有线广域网或者一个无线广域网。
物理层
物理层位于最底层,传输帧中单独的比特。
封装与解封装
源主机的封装:
- 应用层的消息不包含任何头部和尾部,消息直接传输到传输层;
- 传输层把这个消息作为有效载荷,在次基础上添加上传输层头部,比如负责进行流量控制、差错控制和拥塞控制所需要的信息。该分组在TCP中称为段,在UDP中称为用户数据报,然后传递分组到网络层;
- 网络层把分组作为有效载荷,并且在此基础上添加自己的头部,头部包含了源主机和目的主机的地址,以及用于头部检查、分片等其他信息。
- 数据链路层把网络分组作为有效载荷,并在此基础上添加上了自己的头部。该头部包含主机或者下一跳步的链路层地址,结果为一个称为帧的链路层分组。
路由器的解封装与封装:
- 路由器会解封装来自源主机的帧,获取齐总的数据报将他投递到网络层。
- 网络层检查数据报头部的源地址和目的地址,查阅它的转发表以寻找该数据报将被投递到的下一跳步,除非数据报太大以至于不能通过下一链路时需要对其进行分片,数据报的内容不应该被网络层改变,然后数据报被传递到下一链路的数据链路层;
- 下一链路的数据链路层将数据报封装成一个帧,将其传递到物理层进行传输。
应用层
客户端进程是怎么和服务器进程通信的?
应用程序接口
计算机语言有一个数学操作指令集、一个字符串处理指令集、一个输入/输出访问指令集。如果我们想要一个进程与另一个进程通信,那么我们就需要一个新的指令集告知 TCP/IP 协议族的低四层打开连接,发送数据,从另一个终端接收数据以及关闭连接,这样的指令集通常称为应用程序接口。
其中很常见的三个接口:套接字接口、传输层接口、STREAM。最常见的是套接字接口,套接字接口是提供应用层和操作系统间通信的指令集,是一个可以被某进程用来与另一个进程进行通信的指令集。
套接字
就应用层而言,客户进程和服务器进程间的通信是两个套接字间的通信,如果我们创建两个套接字,一端创建一个,并正确定义源端和目的端地址,那么我们就可以使用指令去发送和接收数据了,其余就是操作系统以及嵌入的 TCP/IP 协议的工作了。
套接字的地址是由 32位的IP地址 + 16位的端口号组成。
套接字地址
服务器站点:
- 本地套接字地址,操作系统知道运行着服务器进程的计算机的IP地址。然而服务器进程的端口号需要被分配,如果这个服务器进程是因特网管理结构定义的标准进程,那么端口号就已经分配好了,比如超文本传输控制协议(80端口);非标准进程会由设计者在规定范围内选择一个端口号。
- 远程套接字地址,对服务器来说,远程套接字地址是建立连接的客户套接字地址。会随着连接变动而发生改变;
客户端站点:
- 本地套接字地址,本地套接字地址由操作系统提供,操作系统知道本机IP地址,端口号是每次客户进程开始通信时分配给客户进程的一个临时16位整数。
- 远程套接字地址,当一个客户进程开启时,它会知道自己想要连接的服务器地址。
超文本传输协议(HTTP)
超文本传输协议是一种用来定义客户服务器程序如何编写和使用从万维网获取网页的协议。在HTTP1.1 版本之前是一种非持续链接,HTTP1.1 版本之后默认使用持续链接,持续连接避免了非持续链接带来的高额开销问题,每个站点只需要为连接设定一组缓冲区和变量,同时节省了连接建立和终止的往返时间。
HTTP 与 TCP/IP 的区别?
TCP/IP 协议是传输层协议,主要用来解决数据如何在网络中传输;而HTTP是应用层协议,主要解决如何包装数据,WEB使用 HTTP协议作为应用层协议,以封装HTTP文本信息,然后使用 TCP/IP 做传输层协议将它发到网络上。
请求报文和响应报文的组成格式:
请求报文:
- 请求行:包括请求方法(GET、HEAD、PUT、POST、TRACE、CONNECT、DELETE、OPTIONS);请求URL;协议版本;
- 请求头:从客户端向服务器发送的额外信息,比如
User-agent
、Accept
、Authorization
、Cookie
;
- 请求空行;
- 请求体:请求的具体内容。
响应报文:
- 状态行:包括协议版本、状态码、短语。100范围内的状态码只代表一个报告、200范围内代码表示这是一个成功的请求、300范围内代码表示把客户端重定向到另一个URL、400范围内代码表示在客户端发生错误、500范围内代码表示错误发生在服务器端。
- 响应头:服务器端的一些需要返回给客户端的信息。
HTTP 支持代理服务器,代理服务器是一台计算机,能够保存最近请求的响应的副本。代理服务器降低了原服务器的负载,减少了通信量并降低了延迟。
代理服务器通常使用在:1) 客户计算机作为小容量代理服务器,存储着与客户经常调用的请求的响应;2) 公司内部的代理服务器安装在计算机LAN中来减少进出LAN的负载; 3) 带有很多客户的ISP可以安装一台代理服务器来减少进出ISP网络的负载。
HTTP本质上并不安全,但是可以在安全套接层(SSL) 上运行,在这种情况下 HTTP称为 HTTPS,HTTPS提供保密性、客户和服务器鉴别,以及数据完整性。
安全应用层协议 HTTPS
HTTPS 在 HTTP 基础上加入了 SSL协议,SSL协议依靠证书来验证服务器的身份,并为服务器和浏览器之间的通信加密。加密过程如下:
- 客户端发起 HTTPS 请求;
- HTTPS协议的服务端拥有一套数字证书,可以是自己制作或者CA证书。区别在于CA证书能够直接使用,而自己制作的证书需要客户端验证通过才可以继续访问。总的来说该证书实际上看作一对公钥和私钥,公钥给别人加密使用,私钥给自己解密使用;
- 服务端传送证书给客户端;
- 客户端解析证书,比如证书的颁发机构、过期时间等,如果发现异常会进行提示。如果通过检查,就生成一个随机值,并利用证书对该随机值进行加密;
- 客户端传送加密后的随机值,目的在于让服务端接收该随机值并在之后的通信过程中利用该随机值进行加密解密;
- 服务端利用证书对加密后的随机值进行解密,得到客户端传送过来的随机值(该值作为之后传输过程中的私钥使用)。然后利用随机值对发送内容进行对称加密,正好客户端和服务端都知道这个私钥(客户端传输的随机值),所以只有两者能够对消息进行解密;
- 传输加密后的信息;
- 客户端利用生成的私钥对信息进行解密,获得解密后的内容。
整个过程中即使信息泄露,外部也会因为不知道私钥而无法解密信息,所以是安全的。
HTTP 和 HTTPS 的区别:
- https 协议需要到 ca 申请证书或者自制证书;
- http 信息是明文传输,https 信息则是具有安全性的 ssl 加密;
- http 直接与 tcp 进行数据传输,而 https 还需要经过一层 SSL,用的端口也不一样,前者是80端口,后者是443端口;
- http 的连接很简单,是无状态的;https 协议是由 SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比 HTTP协议安全;
HTTPS 协议的数据加密是在传输层进行,无论是 HTTPS 的header域还是 body域都会被加密处理。
文件传输协议(FTP)
文件传输协议FTP 是TCP/IP 提供的标准机制,用于将文件从一个主机复制到另一个主机。FTP结构上由客户端和服务器端组成,客户端包括用户接口、控制进程、数据传输进程三个组件;服务器端包括控制进程、数据传输进程组成。
FTP中两种连接有不同的寿命,在整个FTP会话期间,控制连接始终处于连接状态。数据连接则在每次完成传输文件时开启然后关闭。数据连接通过20端口进行操作,控制连接通过21端口。
控制连接
对于控制通信,FTP使用与TELNET相同的方法。它与TELNET一样使用NVT ASCII 字符集。在控制连接期间,命令从客户端发送到服务器并且响应从服务器发送到客户端。
每个FTP命令至少产生一个响应,一个响应由两部分组成:文本 + 一个三位数字,数字部分定义了编码。
数据连接
数据连接使用 20端口,数据连接的创建步骤如下:
- 客户使用临时端口发起一个被动打开,必须由客户完成,因为是客户发出命令要求传输文件的;
- 客户使用 PORT 命令发送这个端口号到服务器;
- 服务器接收到端口号,使用熟知端口20发出主动打开并且接收临时端口号。
数据连接建立后不能立刻通信,还需要定义传输文件的类型、数据结构、传输模式,因此通过建立控制连接来完成:
- 规定传输数据的数据结构:FTP可以使用下列数据结构中的一种在数据连接上传送文件:文件结构、记录结构、页面结构。其中文件结构是默认使用,它是连续的字节流;记录结构把文件划分成了一个个记录,只能用于文本文件;页面结构把文件划分成页面,每一个页面有一个页面号和一个页面头部,页面可以随机地或者顺序地存储或访问。
- 规定传输数据地文件类型:FTP可以在数据连接上传输下列文件的一种:ASCII文件、EBCDIC文件、图像文件;
- 规定传输数据的传输方式:三种方式,流方式、块方式、压缩方式。块方式中在文件前加上了一个3字节的文件头,其中第一个字节称为块描述,后面两个字节定义块大小。
完成控制连接后就可以开始进行数据传输了。
简单电子邮件传输协议(SMTP)
电子邮件传输模式架构
邮件传输通过代理服务器完成,包括三种不同的代理,用户代理(UA)、报文传输代理(MTA)、报文访问代理(MAA)。
报文传输代理 SMTP
报文首先从客户经过MTA报文传输代理发送到客户端的邮件服务器,然后再从客户端邮件服务器经过MTA报文传输代理发送到服务端邮件服务器,服务端邮件服务器再通过MAA报文访问代理发送给具体的用户。
MTA客户机和服务器常用的协议称为**简单邮件传输协议(SMTP)**,SMTP只定义了如何来回发送命令和响应,因此在邮件服务器和接收器之间还需要另一个协议。
SMTP协议涉及到的邮件传输阶段分为三个:连接建立、邮件传输、连接终止。
SMTP协议是一个推协议,他将报文从客户推入服务器,但是第三阶段需要一个拉协议,客户机必须从服务器拉出报文,大量数据的方向是从服务器到客户,因此第三阶段使用报文访问代理协议。目前的MAA协议主要有邮局协议版本3(POP3)、因特网邮件访问协议版本4(IMAP4)。
基于Web的邮件
以上是传统邮件传输服务的架构组织,现在出现了另一种架构模式。报文从发送邮件服务器到接收邮件服务器的传输仍然是通过SMTP来完成的,但是从接收服务器到浏览器是通过HTTP来完成的。
远程登陆 TELNET、SSH
TELNET
远程登陆协议之一是TELNET
。在输入命令进行远程登陆时,用户将击键发送给终端驱动程序,同时本地操作系统接收这些字符,但并不解释它们。这些字符被发送到TELNET客户机,它将这些字符转换为网络虚拟终端(Network Virtual Terminal,NVT)字符的通用字符集,然后将其传送给本地 TCP/IP 协议栈。
采用网络虚拟终端NVT 形式的命令或文本通过因特网传送到远程的TCP/IP 协议栈,在那里传递给操作系统,操作系统再移交给TELNET服务器,TELNET服务器将这些字符转换为远程计算机可以理解的字符。但是这些字符不能直接传递给操作系统,因为操作系统不能处理来自TELNET服务器的字符,它只能接收来自终端驱动程序的字符。所以还需要在远程端增加一个伪终端驱动程序的软件块。
SSH
TELNET虽然能够进行远程登陆和消息传递,但是并不安全。更加安全的协议是SSH(Secure Shell),它是一个可以用于远程登陆和文件传输的多用途安全应用协议,SSH是一个有三个组件的应用层协议。
三个组件包括:SSH-TRANS(SSH应用层协议)、SSH-AUTH(SSH认证协议)、SSH-CONN(SSH连接协议)。
SSH-TRANS:是一个独立协议,当执行这个协议的程序被调用时,客户和服务器首先通过TCP建立一个不安全的连接,然后交换它们的几个参数在TCP顶部建立安全信道。
SSH-AUTH:在客户与服务器之间的安全信道建立以及客户端认证服务器之后,SSH可以调用另外一个流程,它为服务器对客户进行认证。
SSH-CONN:在安全信道建立和服务器相互认证之后,SSH可以调用一个执行第三个协议的软件,那就是SSH-CONN。SSH-CONN 协议提供的一个服务是复用。SSH-CONN 采用前两层协议创建安全信道并允许客户在其上创建多个逻辑信道,每个逻辑信道可以用于不同目的,比如文件传输、远程登陆等。
端口转发:SSH提供一个特殊的服务端口转发,我们可以使用SSH中可用的安全信道来访问一个不提供安全服务的应用程序。比如TELNET和简单邮件传输协议(SMTP) 这类应用。SSH端口转发机制创建了一个隧道,属于其它协议的报文可以穿过这个隧道。
域名系统 DNS
举个栗子:网络上常见的文件传输,就用到了DNS域名解析功能。
域名系统结构
y
域名空间的结构是一棵多叉树,这棵树总共有128级,0级(根结点)至127级。
标签:树上面的每一个结点都有一个标签,标签是一个最多63个字符的字符串,根节点符号是空串,DNS要求每一个结点的子结点有不同的标签,这样保证了域名的唯一性。
域名:树上的每一个节点都有一个域名,域名是通过 . 分隔开的标签序列。
域:域是域命名空间的子树,域的名称是子树顶端结点的名称。
区域:树的部分区域,服务器内有一个数据库,称为区域文件,它保存着这个域里所有的结点信息。
根服务器:根服务器通常不保存关于域的任何信息,只是将其委托给其它服务器,并保持与这些服务器的参照关系。
主服务器和辅助服务器:主服务器是指存储了授权区域有关文件的服务器。它负责创建、维护、更新区域文件,并将区域文件存储在本地磁盘中。辅助服务器则是负责从另一个服务器传输一个区域的全部信息,并将文件存储在它的本地磁盘中,辅助服务器不负责更新区域文件,如果需要更新只能由主服务器完成,然后再发给辅服务器。
域名解析
- 递归解析:本地服务器通常不能一次获取到目标域名的IP地址,所以需要经过多个域名服务器的转发来识别。递归解析特点就在于每次转发获取到下一跳DNS服务器的IP地址后就由当前DNS服务器继续向下转发,而不是返还给初始本地DNS服务器来访问。
- 迭代解析:每次获取到下一跳DNS 域名服务器的IP地址后,返还给初始本地DNS域名服务器进行访问。
DNS报文
DNS报文分为查询报文和响应报文,两种报文都有相同的格式。
- 标识:用来匹配对查询的响应。
- 标记:定义了报文是响应报文还是查询报文。
DNS可以只使用UDP或者TCP报文,在这两种情况下使用的是53端口,当响应报文的长度小于512字节就需要使用UDP,如果报文长度大于512字节就需要使用TCP。
对等模式 (P2P)
客户服务器模式,总体上分为两类:集中式和分散式。
集中式网络:在集中式P2P网络中,目录系统列出了对等节点以及它们提供的内容。一个寻找特定文件的对等结点向中心服务器发送一个查询,服务器搜索其目录,将含有所需文件副本的多个结点的IP地址作为响应返回对等结点。对等结点与其中一个结点连接并下载文件,当有结点加入或者离开时,目录立即进行更新。
集中式网络缺点在于当流量巨大时会导致系统速度降低。
分散式网络:分散式网络并不依赖于中心化目录系统。而是依照覆盖网的结构进行设计。包括两种网络:结构化网络、非结构化网络。
非结构化网络的效率比较低,因为结点随机连接,结点的搜索效率不高,因为对一个文件的查询必须通过网络进行泛洪,这将造成极大的通信量。
结构化网络采用一组预先确定的规则来连接结点,有效并高效地解决查询,最常用的技术是分布式散列表(Distributed Hash Table)。
分布式散列表 (Distributed Hash Table, DHT)
分布式散列表根据预先定义的规则将数据分发到一组结点上。对于基于DHT的网络,每一个对等节点负责一系列数据项。为了避免我们在非结构化P2P网络中讨论的洪泛开销,基于DHT的网络允许每个对等结点对整个网络做部分了解。
DHT的主要功能是将一个查询路由到负责存储这个对象引用的结点上,每个结点必须对整个环有部分了解,从而将查询路由到与负责结点最接近的一个结点上。
通俗来说就是将网络中的计算机结点哈希映射到圆形哈希表上的不同位置,同时将这些主机上的文件也经过哈希映射到哈希表上。文件对象保存在相应的计算节点上,但是文件对象的引用存储在另一个结点上(该结点的ID最接近关键字)。
在基于DHT的网络中,每个数据项被映射到了大小为 2^m 的地址上,绝大多数DHT使用的 m=160。
散列对等结点标识符:创建DHT的第一步是将所有对等结点放入地址空间环中,通过散列函数:结点ID = hash(对等结点IP地址)
来计算。
散列对象标识符:被共享的文件的名称的散列结果称为关键字,通过函数 关键字 = hash(对象名)
来计算,在DHT中一个对象通常和一组 (key,value) 相关,其中 key 是对象名的散列值,value是对象或者对象的引用。
绝大多数DHT系统使用间接方法,即拥有对象的对等结点保存对象,但是对象的引用被创建并存储在另一个结点上,这个结点的ID最接近关键字。
DHT算法 —— chord
- 算法要素:
标识符空间:对等结点和数据项(比如一个需要共享的文件)同时按照顺时针分布在一个环上,我们将数据项的标识符称为k(即key,关键字),对等节点的标识符为 N(即node,结点)。最接近 N ≥ k 的对等结点称作关键字 k 的后向结点并且拥有数值 (k,v),其中 k是关键字(数据项的散列值),v是拥有对象的对等结点服务器的信息。 也就是说文件这类数据存储在拥有数据项的对等结点上,但是数据项的散列值key以及对等结点的信息value被作为一对(k,v) 存储在 k 的后向结点上。
指针表:为了找到目标关键字所在的对等结点,需要通过结点间的转发来不断查找,因此设计了指针表。 Chord 要求每一个结点维护 m 的后向结点以及一个前向结点的信息,每个结点创建一个称为指针表的路由表。Chord 环中每个结点的第一个指针给出了后向结点的ID。
通过指针表每个结点就能认识到哈希表中其它结点的信息。
- 算法关键方法 —— 查找
lookup(key)
函数调用 find_successor(id)
函数来找到这个ID的后向结点,在查找后向结点时可以通过前向结点来迭代查找,因为前向结点的第一个指针(finger[1]
)给出了后向结点的ID。
一个结点需要其它结点的帮助来找到关键字 key 的前向结点,这一步可以将 find_closest_predecessor(id)
函数作为远程程序调用RPC
来完成。
DHT算法 —— Pastry
待续。。。。。
DHT算法 —— Kademlia
待续。。。。
套接字Socket
套接字的数据结构
套接字并没有存储待发送或者待接收数据的缓冲区,它既不能发送也不能接收数据,套接字只是起到一个引用或标签的作用。缓冲区和必要的变量在操作系统中创建。
- 族:定义了协议簇。通常是
PF_INET
、PF_INET6(下一代因特网)
。 - 类型:套接字的四种类型。
SOCK_STREAM(用于TCP)
、SOCK_DGRAM(用于UDP)
、SOCK_SEQPACKET(用于SCTP)
、SOCK_RAW(用于直接使用ISP服务的应用)
。 - 协议:定义了族中特定协议。对于 TCP/IP 协议族字段设置为0。
- 本地套接字地址。套接字地址由 长度字段、族字段、端口号字段、IP地址字段构成。
- 远程套接字地址。
UDP通信过程
UDP通信中客户和服务器每一端只使用一个套接字,服务器创建的套接字永远运行,而且服务器只创建一个套接字。客户端的套接字在每次通信结束时被销毁关闭。
- 服务器进程:服务器进程被动开启。首先通过
socket()
函数创建套接字,在这个程序调用中填充了套接字的前三个字段,但是本地和远程套接字地址字段仍然未定义。之后服务器进程调用bind()
函数来填充本地套接字地址字段(信息来自操作系统)。然后调用recvfrom()
函数阻塞服务器进程直到一个客户数据报到达。当下一个数据报到达时,服务器进程接触阻塞并且从数据报中抽取出发送套接字地址,填充到套接字的远程套接字地址字段。这样完成了全部套接字字段的填充,通过sento()
函数来完成数据的发送。 - 客户端进程:客户进程主动开启。首先通过
socket()
函数创建一个套接字并填充到前三个字段,它不需要通过bind()
函数来填充本地套接字地址,这个操作由操作系统自动完成,它会选择一个临时端口号。之后进程调用sendto()
函数,并提供远程套接字地址信息,这个套接字地址必须由客户进程的用户提供。套接字完成填充就进行数据发送,接着调用recvfrom()
函数,阻塞了客户进程直到响应来自服务器进程。此外没有必要从这个函数中提取远程套接字地址,因为此处不需要调用sendto()
函数。 - 总结:服务端和客户端的
recvfrom()
函数行为不同,在服务器进程中,recvfrom()
函数首先被调用获取远程套接字地址然后调用sendto()
发送数据。在客户端进程中,sendto()
函数先调用发送数据,此时远程套接字地址由程序使用者提供。
TCP通信过程
TCP是面向连接的协议,所以需要先建立连接再发送或者接收数据。TCP服务端使用两个不同的套接字,一个用于建立连接,一个用于数据传输。设置两个套接字的目的是为了将建立阶段和数据传输阶段分隔开。客户端只使用一个套接字用于连接建立和数据交换。
服务器进程:首先调用
socket()
和bind()
函数创建监听套接字,它只在建立连接阶段使用。之后服务器调用listen()
函数允许客户端开始接收客户,完成客户连接并将它们放入到等待被服务的列表。接着服务器进程开始循环并且逐一对客户进行服务,每次循环过程中调用accept()
函数从已连接客户的等待列表中去除一个客户,对其进行服务。当accept()
函数返回时,它会创建一个新的套接字用来进行数据传输,监听套接字此时就移入到后台,并且新的套接字称为活动套接字。服务器进程此时使用连接建立阶段获取的客户端套接字地址作为远程套接字地址。TCP服务器使用
send()
以及recv()
函数在两者之间进行数据传递。这两个函数比UDP中的sendto()
、recvfrom()
更简单,它不需要提供远程套接字地址,因为连接已经在两者之间建立起来了。同时由于TCP多用于传输无边界报文,所以send()
、recv()
函数可能被调用用来多次处理大量数据传输。