收藏 分享(赏)

10--Linux网络编程-网络基础-socket编程-高并发服务器.doc

上传人:精品资料 文档编号:9446447 上传时间:2019-08-08 格式:DOC 页数:77 大小:1.01MB
下载 相关 举报
10--Linux网络编程-网络基础-socket编程-高并发服务器.doc_第1页
第1页 / 共77页
10--Linux网络编程-网络基础-socket编程-高并发服务器.doc_第2页
第2页 / 共77页
10--Linux网络编程-网络基础-socket编程-高并发服务器.doc_第3页
第3页 / 共77页
10--Linux网络编程-网络基础-socket编程-高并发服务器.doc_第4页
第4页 / 共77页
10--Linux网络编程-网络基础-socket编程-高并发服务器.doc_第5页
第5页 / 共77页
点击查看更多>>
资源描述

1、网络基础协议的概念什么是协议从应用的角度出发,协议可理解为“规则” ,是数据传输和数据的解释的规则。假设,A、B 双方欲传输文件。规定:第一次,传输文件名,接收方接收到文件名,应答 OK 给传输方;第二次,发送文件的尺寸,接收方接收到该数据再次应答一个 OK;第三次,传输文件内容。同样,接收方接收数据完成后应答 OK 表示文件内容接收成功。由此,无论 A、B 之间传递何种文件,都是通过三次数据传输来完成。A 、B 之间形成了一个最简单的数据传输规则。双方都按此规则发送、接收数据。A、B 之间达成的这个相互遵守的规则即为协议。这种仅在 A、B 之间被遵守的协议称之为 原始协议。当此协议被更多的人

2、采用,不断的增加、改进、维护、完善。最终形成一个稳定的、完整的文件传输协议,被广泛应用于各种文件传输过程中。该协议就成为一个标准协议。最早的 ftp 协议就是由此衍生而来。TCP 协议注重数据的传输。http 协议着重于数据的解释。典型协议传输层 常见协议有 TCP/UDP 协议。应用层 常见的协议有 HTTP 协议,FTP 协议。网络层 常见协议有 IP 协议、ICMP 协议、IGMP 协议。网络接口层 常见协议有 ARP 协议、RARP 协议。TCP 传输控制协议(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。UDP 用户

3、数据报协议(User Datagram Protocol)是 OSI 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。HTTP 超文本传输协议(Hyper Text Transfer Protocol)是互联网 上应用最为广泛的一种网络协议。FTP 文件传输协议(File Transfer Protocol)IP 协议是因特网互联协议(Internet Protocol)ICMP 协议是 Internet 控制报文协议(Internet Control Message Protocol)它是 TCP/IP 协议族的一个子协议,用于在 IP 主机、路由器之间传递控制消息。

4、IGMP 协议是 Internet 组管理协议(Internet Group Management Protocol) ,是因特网协议家族中的一个组播协议。该协议运行在主机和组播路由器之间。ARP 协议是正向 地址解析协议 (Address Resolution Protocol) ,通过已知的 IP,寻找对应主机的 MAC 地址。RARP 是反向地址转换协议,通过 MAC 地址确定 IP 地址。网络应用程序设计模式C/S 模式传统的网络应用设计模式,客户机(client)/服务器(server)模式。需要在通讯两端各自部署客户机和服务器来完成数据通信。B/S 模式浏览器()/服务器 (ser

5、ver)模式。只需在一端部署服务器,而另外一端使用每台 PC 都默认配置的浏览器即可完成数据的传输。优缺点对于 C/S 模式来说,其优点明显。客户端位于目标主机上可以保证性能,将数据缓存至客户端本地,从而提高数据传输效率。且,一般来说客户端和服务器程序由一个开发团队创作,所以他们之间所采用的协议相对灵活。可以在标准协议的基础上根据需求裁剪及定制。例如,腾讯公司所采用的通信协议,即为 ftp 协议的修改剪裁版。因此,传统的网络应用程序及较大型的网络应用程序都首选 C/S 模式进行开发。如,知名的网络游戏魔兽世界。3D 画面,数据量庞大,使用 C/S 模式可以提前在本地进行大量数据的缓存处理,从而

6、提高观感。C/S 模式的缺点也较突出。由于客户端和服务器都需要有一个开发团队来完成开发。工作量将成倍提升,开发周期较长。另外,从用户角度出发,需要将客户端安插至用户主机上,对用户主机的安全性构成威胁。这也是很多用户不愿使用 C/S 模式应用程序的重要原因。B/S 模式相比 C/S 模式而言,由于它没有独立的客户端,使用标准浏览器作为客户端,其工作开发量较小。只需开发服务器端即可。另外由于其采用浏览器显示数据,因此移植性非常好,不受平台限制。如早期的偷菜游戏,在各个平台上都可以完美运行。B/S 模式的缺点也较明显。由于使用第三方浏览器,因此网络应用支持受限。另外,没有客户端放到对方主机上,缓存数

7、据不尽如人意,从而传输数据量受到限制。应用的观感大打折扣。第三,必须与浏览器一样,采用标准 http 协议进行通信,协议选择不灵活。因此在开发过程中,模式的选择由上述各自的特点决定。根据实际需求选择应用程序设计模式。分层模型OSI 七层模型OSI 模型1. 物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由 1、0 转化为电流强弱来进行传输,到达目的地后再转化为 1、0,也就是我们常说的数模转换与模数转换) 。这一层的数据叫做比特。2. 数据链路层:定义了如何让格式化数据以帧为单位进行传输,以及如何让控制对物理介质的访问。

8、这一层通常还提供错误检测和纠正,以确保数据的可靠传输。如:串口通信中使用到的 115200、8、N、13. 网络层:在位于不同地理位置的网络中的两个主机系统之间提供连接和路径选择。Internet 的发展使得从世界各站点访问信息的用户数大大增加,而网络层正是管理这种连接的层。4. 传输层:定义了一些传输数据的协议和端口号(WWW 端口 80 等) ,如:TCP(传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据) ,UDP(用户数据报协议,与 TCP 特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如 QQ 聊天数据就是通过这种方式传输的) 。 主要是将从下层接收的

9、数据进行分段和传输,到达目的地址后再进行重组。常常把这一层数据叫做段。5. 会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是 IP 也可以是 MAC 或者是主机名) 。6. 表示层:可确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。例如,PC 程序与另一台计算机进行通信,其中一台计算机使用扩展二一十进制交换码(EBCDIC),而另一台则使用美国信息交换标准码(ASCII)来表示相同的字符。如有必要,表示层会通过使用一种通格式来实现多种数据格式之间的转换。7. 应用层:是最靠近用户的 OSI

10、层。这一层为用户的应用程序(例如电子邮件、文件传输和终端仿真)提供网络服务。TCP/IP 四层模型TCP/IP 网络协议栈分为应用层(Application) 、传输层(Transport) 、网络层(Network)和链路层(Link)四层。如下图所示:TCP/IP 模型一般在应用开发过程中,讨论最多的是 TCP/IP 模型。通信过程两台计算机通过 TCP/IP 协议通讯的过程如下所示:TCP/IP 通信过程上图对应两台计算机在同一网段中的情况,如果两台计算机在不同的网段中,那么数据从一台计算机到另一台计算机传输过程中要经过一个或多个路由器,如下图所示:跨路由通信链路层有以太网、令牌环网等标

11、准,链路层负责网卡设备的驱动、帧同步(即从网线上检测到什么信号算作新帧的开始) 、冲突检测(如果检测到冲突就自动重发) 、数据差错校验等工作。交换机是工作在链路层的网络设备,可以在不同的链路层网络之间转发数据帧(比如十兆以太网和百兆以太网之间、以太网和令牌环网之间) ,由于不同链路层的帧格式不同,交换机要将进来的数据包拆掉链路层首部重新封装之后再转发。网络层的 IP 协议是构成 Internet 的基础。Internet 上的主机通过 IP 地址来标识,Inter-net 上有大量路由器负责根据 IP 地址选择合适的路径转发数据包,数据包从 Internet 上的源主机到目的主机往往要经过十多

12、个路由器。路由器是工作在第三层的网络设备,同时兼有交换机的功能,可以在不同的链路层接口之间转发数据包,因此路由器需要将进来的数据包拆掉网络层和链路层两层首部并重新封装。IP 协议不保证传输的可靠性,数据包在传输过程中可能丢失,可靠性可以在上层协议或应用程序中提供支持。网络层负责点到点(ptop,point-to-point)的传输(这里的“点”指主机或路由器) ,而传输层负责端到端(etoe, end-to-end)的传输(这里的“端”指源主机和目的主机) 。传输层可选择 TCP 或 UDP 协议。TCP 是一种面向连接的、可靠的协议,有点像打电话,双方拿起电话互通身份之后就建立了连接,然后说

13、话就行了,这边说的话那边保证听得到,并且是按说话的顺序听到的,说完话挂机断开连接。也就是说 TCP 传输的双方需要首先建立连接,之后由 TCP 协议保证数据收发的可靠性,丢失的数据包自动重发,上层应用程序收到的总是可靠的数据流,通讯之后关闭连接。UDP 是无连接的传输协议,不保证可靠性,有点像寄信,信写好放到邮筒里,既不能保证信件在邮递过程中不会丢失,也不能保证信件寄送顺序。使用 UDP 协议的应用程序需要自己完成丢包重发、消息排序等工作。目的主机收到数据包后,如何经过各层协议栈最后到达应用程序呢?其过程如下图所示:以太网驱动程序首先根据以太网首部中的“上层协议”字段确定该数据帧的有效载荷(p

14、ayload,指除去协议首部之外实际传输的数据)是 IP、ARP 还是 RARP 协议的数据报,然后交给相应的协议处理。假如是 IP 数据报, IP协议再根据 IP 首部中的“上层协议”字段确定该数据报的有效载荷是 TCP、UDP、ICMP 还是 IGMP,然后交给相应的协议处理。假如是 TCP 段或 UDP 段,TCP 或 UDP 协议再根据 TCP 首部或 UDP 首部的“端口号”字段确定应该将应用层数据交给哪个用户进程。IP 地址是标识网络中不同主机的地址,而端口号就是同一台主机上标识不同进程的地址,IP 地址和端口号合起来标识网络中唯一的进程。虽然 IP、ARP 和 RARP 数据报都

15、需要以太网驱动程序来封装成帧,但是从功能上划分,ARP 和 RARP 属于链路层,IP 属于网络层。虽然 ICMP、IGMP 、TCP、UDP 的数据都需要 IP 协议来封装成数据报,但是从功能上划分,ICMP、IGMP 与 IP 同属于网络层,TCP 和 UDP 属于传输层。协议格式数据包封装传输层及其以下的机制由内核提供,应用层由用户进程提供(后面将介绍如何使用 socket API 编写应用程序) ,应用程序对通讯数据的含义进行解释,而传输层及其以下处理通讯的细节,将数据从一台计算机通过一定的路径发送到另一台计算机。应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(head

16、er) ,称为封装(Encapsulation ) ,如下图所示:TCP/TP 数据包封装不同的协议层对数据包有不同的称谓,在传输层叫做段(segment) ,在网络层叫做数据报(datagram) ,在链路层叫做帧(frame) 。数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理。以太网帧格式以太网的帧格式如下所示:以太网帧格式其中的源地址和目的地址是指网卡的硬件地址(也叫 MAC 地址) ,长度是 48 位,是在网卡出厂时固化的。可在 shell 中使用 ifconfig 命令查看, “HWaddr 00:15:F2:14:9E:3F”

17、部分就是硬件地址。协议字段有三种值,分别对应IP、ARP、RARP 。帧尾是 CRC 校验码。以太网帧中的数据长度规定最小 46 字节,最大 1500 字节,ARP 和 RARP 数据包的长度不够 46 字节,要在后面补填充位。最大值 1500 称为以太网的最大传输单元( MTU) ,不同的网络类型有不同的 MTU,如果一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的 MTU,则需要对数据包进行分片(fragmentation) 。ifconfig 命令输出中也有“MTU:1500” 。注意,MTU 这个概念指数据帧中有效载荷的最大长度,不包括帧头长度。ARP 数据报格式在网络通讯

18、时,源主机的应用程序知道目的主机的 IP 地址和端口号,却不知道目的主机的硬件地址,而数据包首先是被网卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则直接丢弃。因此在通讯前必须获得目的主机的硬件地址。ARP 协议就起到这个作用。源主机发出 ARP 请求,询问“IP 地址是192.168.0.1 的主机的硬件地址是多少” ,并将这个请求广播到本地网段(以太网帧首部的硬件地址填FF:FF:FF:FF:FF:FF 表示广播) ,目的主机接收到广播的 ARP 请求,发现其中的 IP 地址与本机相符,则发送一个 ARP应答数据包给源主机,将自己的硬件地址填写在应答包中。每台主机都维

19、护一个 ARP 缓存表,可以用 arp -a 命令查看。缓存表中的表项有过期时间(一般为 20 分钟) ,如果 20 分钟内没有再次使用某个表项,则该表项失效,下次还要发 ARP 请求来获得目的主机的硬件地址。想一想,为什么表项要有过期时间而不是一直有效?ARP 数据报的格式如下所示:ARP 数据报格式源 MAC 地址、目的 MAC 地址在以太网首部和 ARP 请求中各出现一次,对于链路层为以太网的情况是多余的,但如果链路层是其它类型的网络则有可能是必要的。硬件类型指链路层网络类型,1 为以太网,协议类型指要转换的地址类型,0x0800 为 IP 地址,后面两个地址长度对于以太网地址和 IP

20、地址分别为 6 和 4(字节) ,op 字段为 1表示 ARP 请求, op 字段为 2 表示 ARP 应答。看一个具体的例子。请求帧如下(为了清晰在每行的前面加了字节计数,每行 16 个字节):以太网首部(14 字节)0000: ff ff ff ff ff ff 00 05 5d 61 58 a8 08 06ARP 帧(28 字节)0000: 00 010010: 08 00 06 04 00 01 00 05 5d 61 58 a8 c0 a8 00 370020: 00 00 00 00 00 00 c0 a8 00 02填充位(18 字节)0020: 00 77 31 d2 50 1

21、00030: fd 78 41 d3 00 00 00 00 00 00 00 00以太网首部:目的主机采用广播地址,源主机的 MAC 地址是 00:05:5d:61:58:a8,上层协议类型 0x0806 表示ARP。ARP 帧:硬件类型 0x0001 表示以太网,协议类型 0x0800 表示 IP 协议,硬件地址(MAC 地址)长度为 6,协议地址(IP 地址)长度为 4,op 为 0x0001 表示请求目的主机的 MAC 地址,源主机 MAC 地址为00:05:5d:61:58:a8,源主机 IP 地址为 c0 a8 00 37(192.168.0.55) ,目的主机 MAC 地址全 0

22、 待填写,目的主机 IP 地址为 c0 a8 00 02(192.168.0.2 ) 。由于以太网规定最小数据长度为 46 字节,ARP 帧长度只有 28 字节,因此有 18 字节填充位,填充位的内容没有定义,与具体实现相关。应答帧如下:以太网首部0000: 00 05 5d 61 58 a8 00 05 5d a1 b8 40 08 06ARP 帧0000: 00 010010: 08 00 06 04 00 02 00 05 5d a1 b8 40 c0 a8 00 020020: 00 05 5d 61 58 a8 c0 a8 00 37填充位0020: 00 77 31 d2 50 1

23、00030: fd 78 41 d3 00 00 00 00 00 00 00 00以太网首部:目的主机的 MAC 地址是 00:05:5d:61:58:a8,源主机的 MAC 地址是 00:05:5d:a1:b8:40,上层协议类型 0x0806 表示 ARP。ARP 帧:硬件类型 0x0001 表示以太网,协议类型 0x0800 表示 IP 协议,硬件地址(MAC 地址)长度为 6,协议地址(IP 地址)长度为 4,op 为 0x0002 表示应答,源主机 MAC 地址为 00:05:5d:a1:b8:40,源主机 IP 地址为 c0 a8 00 02(192.168.0.2) ,目的主机

24、 MAC 地址为 00:05:5d:61:58:a8,目的主机 IP 地址为 c0 a8 00 37(192.168.0.55) 。思考题:如果源主机和目的主机不在同一网段,ARP 请求的广播帧无法穿过路由器,源主机如何与目的主机通信?IP 段格式IP 数据报格式IP 数据报的首部长度和数据长度都是可变长的,但总是 4 字节的整数倍。对于 IPv4,4 位版本字段是 4。4 位首部长度的数值是以 4 字节为单位的, 最小值为 5,也就是说首部长度最小是 4x5=20 字节,也就是不带任何选项的 IP 首部,4 位能表示的最大值是 15,也就是说首部长度最大是 60 字节。8 位 TOS 字段有

25、 3 个位用来指定 IP 数据报的优先级(目前已经废弃不用) ,还有 4 个位表示可选的服务类型(最小延迟、最大 ?吐量、最大可靠性、最小成本) ,还有一个位总是 0。总长度是整个数据报(包括 IP 首部和 IP 层 payload)的字节数。每传一个 IP 数据报,16 位的标识加 1,可用于分片和重新组装数据报。3 位标志和 13 位片偏移用于分片。TTL (Time to live)是这样用的:源主机为数据包设定一个生存时间,比如 64,每过一个路由器就把该值减 1,如果减到 0 就表示路由已经太长了仍然找不到目的主机的网络,就丢弃该包,因此这个生存时间的单位不是秒,而是跳(hop) 。

26、协议字段指示上层协议是 TCP、UDP、ICMP 还是 IGMP。然后是校验和,只校验 IP 首部,数据的校验由更高层协议负责。IPv4 的 IP地址长度为 32 位。想一想,前面讲了以太网帧中的最小数据长度为 46 字节,不足 46 字节的要用填充字节补上,那么如何界定这 46 字节里前多少个字节是 IP、ARP 或 RARP 数据报而后面是填充字节?UDP 数据报格式UDP 数据段下面分析一帧基于 UDP 的 TFTP 协议帧。以太网首部0000: 00 05 5d 67 d0 b1 00 05 5d 61 58 a8 08 00IP 首部0000: 45 000010: 00 53 93

27、 25 00 00 80 11 25 ec c0 a8 00 37 c0 a80020: 00 01UDP 首部0020: 05 d4 00 45 00 3f ac 40TFTP 协议0020: 00 01 c:q0030: werq.qwe00 netasci0040: i00 blksize00 51200 ti0050: meout00 1000 tsize00 00060: 00 以太网首部:源 MAC 地址是 00:05:5d:61:58:a8,目的 MAC 地址是 00:05:5d:67:d0:b1,上层协议类型0x0800 表示 IP。IP 首部:每一个字节 0x45 包含 4

28、位版本号和 4 位首部长度,版本号为 4,即 IPv4,首部长度为 5,说明 IP 首部不带有选项字段。服务类型为 0,没有使用服务。16 位总长度字段(包括 IP 首部和 IP 层 payload 的长度)为0x0053,即 83 字节,加上以太网首部 14 字节可知整个帧长度是 97 字节。IP 报标识是 0x9325,标志字段和片偏移字段设置为 0x0000,就是 DF=0 允许分片,MF=0 此数据报没有更多分片,没有分片偏移。TTL 是 0x80,也就是128。上层协议 0x11 表示 UDP 协议。IP 首部校验和为 0x25ec,源主机 IP 是 c0 a8 00 37(192.

29、168.0.55) ,目的主机IP 是 c0 a8 00 01(192.168.0.1) 。UDP 首部:源端口号 0x05d4(1492)是客户端的端口号,目的端口号 0x0045(69 )是 TFTP 服务的 well-known 端口号。UDP 报长度为 0x003f,即 63 字节,包括 UDP 首部和 UDP 层 pay-load 的长度。UDP 首部和 UDP 层payload 的校验和为 0xac40。TFTP 是基于文本的协议,各字段之间用字节 0 分隔,开头的 00 01 表示请求读取一个文件,接下来的各字段是:c:qwerq.qwenetasciiblksize 512ti

30、meout 10tsize 0一般的网络通信都是像 TFTP 协议这样,通信的双方分别是客户端和服务器,客户端主动发起请求(上面的例子就是客户端发起的请求帧) ,而服务器被动地等待、接收和应答请求。客户端的 IP 地址和端口号唯一标识了该主机上的 TFTP 客户端进程,服务器的 IP 地址和端口号唯一标识了该主机上的 TFTP 服务进程,由于客户端是主动发起请求的一方,它必须知道服务器的 IP 地址和 TFTP 服务进程的端口号,所以,一些常见的网络协议有默认的服务器端口,例如 HTTP 服务默认 TCP 协议的 80 端口,FTP 服务默认 TCP 协议的 21 端口,TFTP 服务默认 U

31、DP 协议的69 端口(如上例所示) 。在使用客户端程序时,必须指定服务器的主机名或 IP 地址,如果不明确指定端口号则采用默认端口,请读者查阅 ftp、tftp 等程序的 man page 了解如何指定端口号。/etc/services 中列出了所有 well-known 的服务端口和对应的传输层协议,这是由 IANA(Internet Assigned Numbers Authority)规定的,其中有些服务既可以用 TCP 也可以用 UDP,为了清晰,IANA 规定这样的服务采用相同的 TCP 或 UDP 默认端口号,而另外一些TCP 和 UDP 的相同端口号却对应不同的服务。很多服务有

32、 well-known 的端口号,然而客户端程序的端口号却不必是 well-known 的,往往是每次运行客户端程序时由系统自动分配一个空闲的端口号,用完就释放掉,称为 ephemeral 的端口号,想想这是为什么?前面提过,UDP 协议不面向连接,也不保证传输的可靠性,例如:发送端的 UDP 协议层只管把应用层传来的数据封装成段交给 IP 协议层就算完成任务了,如果因为网络故障该段无法发到对方,UDP 协议层也不会给应用层返回任何错误信息。接收端的 UDP 协议层只管把收到的数据根据端口号交给相应的应用程序就算完成任务了,如果发送端发来多个数据包并且在网络上经过不同的路由,到达接收端时顺序已

33、经错乱了,UDP 协议层也不保证按发送时的顺序交给应用层。通常接收端的 UDP 协议层将收到的数据放在一个固定大小的缓冲区中等待应用程序来提取和处理,如果应用程序提取和处理的速度很慢,而发送端发送的速度很快,就会丢失数据包,UDP 协议层并不报告这种错误。因此,使用 UDP 协议的应用程序必须考虑到这些可能的问题并实现适当的解决方案,例如等待应答、超时重发、为数据包编号、流量控制等。一般使用 UDP 协议的应用程序实现都比较简单,只是发送一些对可靠性要求不高的消息,而不发送大量的数据。例如,基于 UDP 的 TFTP 协议一般只用于传送小文件(所以才叫 trivial 的 ftp) ,而基于

34、TCP 的 FTP 协议适用于 各种文件的传输。TCP 协议又是如何用面向连接的服务来代替应用程序解决传输的可靠性问题呢。TCP 数据报格式TCP 数据段与 UDP 协议一样也有源端口号和目的端口号,通讯的双方由 IP 地址和端口号标识。32 位序号、32 位确认序号、窗口大小稍后详细解释。4 位首部长度和 IP 协议头类似,表示 TCP 协议头的长度,以 4 字节为单位,因此 TCP 协议头最长可以是 4x15=60 字节,如果没有选项字段,TCP 协议头最短 20 字节。URG、ACK 、PSH、RST、SYN、FIN 是六个控制位,本节稍后将解释 SYN、ACK、FIN 、RST 四个位

35、,其它位的解释从略。16 位检验和将 TCP 协议头和数据都计算在内。紧急指针和各种选项的解释从略。TCP 协议TCP 通信时序下图是一次 TCP 通讯的时序图。TCP 连接建立断开。包含大家熟知的三次握手和四次握手。TCP 通讯时序在这个例子中,首先客户端主动发起连接、发送请求,然后服务器端响应请求,然后客户端主动关闭连接。两条竖线表示通讯的两端,从上到下表示时间的先后顺序,注意,数据从一端传到网络的另一端也需要时间,所以图中的箭头都是斜的。双方发送的段按时间顺序编号为 1-10,各段中的主要信息在箭头上标出,例如段 2 的箭头上标着 SYN, 8000(0), ACK1001, ,表示该段

36、中的 SYN 位置 1,32 位序号是 8000,该段不携带有效载荷(数据字节数为 0) ,ACK 位置 1,32 位确认序号是 1001,带有一个 mss(Maximum Segment Size,最大报文长度)选项值为1024。建立连接(三次握手)的过程:1. 客户端发送一个带 SYN 标志的 TCP 报文到服务器。这是三次握手过程中的段 1。客户端发出段 1,SYN 位表示连接请求。序号是 1000,这个序号在网络通讯中用作临时的地址,每发一个数据字节,这个序号要加 1,这样在接收端可以根据序号排出数据包的正确顺序,也可以发现丢包的情况,另外,规定 SYN 位和 FIN 位也要占一个序号

37、,这次虽然没发数据,但是由于发了 SYN 位,因此下次再发送应该用序号 1001。mss 表示最大段尺寸,如果一个段太大,封装成帧后超过了链路层的最大帧长度,就必须在 IP 层分片,为了避免这种情况,客户端声明自己的最大段尺寸,建议服务器端发来的段不要超过这个长度。2. 服务器端回应客户端,是三次握手中的第 2 个报文段,同时带 ACK 标志和 SYN 标志。它表示对刚才客户端SYN 的回应;同时又发送 SYN 给客户端,询问客户端是否准备好进行数据通讯。服务器发出段 2,也带有 SYN 位,同时置 ACK 位表示确认,确认序号是 1001,表示“我接收到序号1000 及其以前所有的段,请你下

38、次发送序号为 1001 的段” ,也就是应答了客户端的连接请求,同时也给客户端发出一个连接请求,同时声明最大尺寸为 1024。3. 客户必须再次回应服务器端一个 ACK 报文,这是报文段 3。客户端发出段 3,对服务器的连接请求进行应答,确认序号是 8001。在这个过程中,客户端和服务器分别给对方发了连接请求,也应答了对方的连接请求,其中服务器的请求和应答在一个段中发出,因此一共有三个段用于建立连接,称为“三方握手(three-way-handshake) ”。在建立连接的同时,双方协商了一些信息,例如双方发送序号的初始值、最大段尺寸等。在 TCP 通讯中,如果一方收到另一方发来的段,读出其中

39、的目的端口号,发现本机并没有任何进程使用这个端口,就会应答一个包含 RST 位的段给另一方。例如,服务器并没有任何进程使用 8080 端口,我们却用 telnet 客户端去连接它,服务器收到客户端发来的 SYN 段就会应答一个 RST 段,客户端的 telnet 程序收到 RST 段后报告错误Connection refused:$ telnet 192.168.0.200 8080Trying 192.168.0.200.telnet: Unable to connect to remote host: Connection refused数据传输的过程:1. 客户端发出段 4,包含从序号

40、1001 开始的 20 个字节数据。2. 服务器发出段 5,确认序号为 1021,对序号为 1001-1020 的数据表示确认收到,同时请求发送序号 1021开始的数据,服务器在应答的同时也向客户端发送从序号 8001 开始的 10 个字节数据,这称为 piggyback。3. 客户端发出段 6,对服务器发来的序号为 8001-8010 的数据表示确认收到,请求发送序号 8011 开始的数据。在数据传输过程中,ACK 和确认序号是非常重要的,应用程序交给 TCP 协议发送的数据会暂存在 TCP 层的发送缓冲区中,发出数据包给对方之后,只有收到对方应答的 ACK 段才知道该数据包确实发到了对方,

41、可以从发送缓冲区中释放掉了,如果因为网络故障丢失了数据包或者丢失了对方发回的 ACK 段,经过等待超时后 TCP 协议自动将发送缓冲区中的数据包重发。关闭连接(四次握手)的过程:由于 TCP 连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个 FIN 来终止这个方向的连接。收到一个 FIN 只意味着这一方向上没有数据流动,一个 TCP 连接在收到一个 FIN 后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。1. 客户端发出段 7,FIN 位表示关闭连接的请求。2. 服务器发出段 8,应答客户端的关闭连接请求。3. 服务器发出

42、段 9,其中也包含 FIN 位,向客户端发送关闭连接请求。4. 客户端发出段 10,应答服务器的关闭连接请求。建立连接的过程是三方握手,而关闭连接通常需要 4 个段,服务器的应答和关闭连接请求通常不合并在一个段中,因为有连接半关闭的情况,这种情况下客户端关闭连接之后就不能再发送数据给服务器了,但是服务器还可以发送数据给客户端,直到服务器也关闭连接为止。滑动窗口 (TCP 流量控制 )介绍 UDP 时我们描述了这样的问题:如果发送端发送的速度较快,接收端接收到数据后处理的速度较慢,而接收缓冲区的大小是固定的,就会丢失数据。TCP 协议通过 “滑动窗口(Sliding Window) ”机制解决这

43、一问题。看下图的通讯过程:滑动窗口1. 发送端发起连接,声明最大段尺寸是 1460,初始序号是 0,窗口大小是 4K,表示“我的接收缓冲区还有 4K 字节空闲,你发的数据不要超过 4K”。接收端应答连接请求,声明最大段尺寸是 1024,初始序号是 8000,窗口大小是 6K。发送端应答,三方握手结束。2. 发送端发出段 4-9,每个段带 1K 的数据,发送端根据窗口大小知道接收端的缓冲区满了,因此停止发送数据。3. 接收端的应用程序提走 2K 数据,接收缓冲区又有了 2K 空闲,接收端发出段 10,在应答已收到 6K 数据的同时声明窗口大小为 2K。4. 接收端的应用程序又提走 2K 数据,接

44、收缓冲区有 4K 空闲,接收端发出段 11,重新声明窗口大小为 4K。5. 发送端发出段 12-13,每个段带 2K 数据,段 13 同时还包含 FIN 位。6. 接收端应答接收到的 2K 数据(6145-8192) ,再加上 FIN 位占一个序号 8193,因此应答序号是 8194,连接处于半关闭状态,接收端同时声明窗口大小为 2K。7. 接收端的应用程序提走 2K 数据,接收端重新声明窗口大小为 4K。8. 接收端的应用程序提走剩下的 2K 数据,接收缓冲区全空,接收端重新声明窗口大小为 6K。9. 接收端的应用程序在提走全部数据后,决定关闭连接,发出段 17 包含 FIN 位,发送端应答

45、,连接完全关闭。上图在接收端用小方块表示 1K 数据,实心的小方块表示已接收到的数据,虚线框表示接收缓冲区,因此套在虚线框中的空心小方块表示窗口大小,从图中可以看出,随着应用程序提走数据,虚线框是向右滑动的,因此称为滑动窗口。从这个例子还可以看出,发送端是一 K 一 K 地发送数据,而接收端的应用程序可以两 K 两 K 地提走数据,当然也有可能一次提走 3K 或 6K 数据,或者一次只提走几个字节的数据。也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream) ,在底层通讯中这些数据可能被拆成很多数据包来发送,但是一个数据包有多少字节对应用程序是不可见的,因此 TCP 协议是面向

46、流的协议。而 UDP 是面向消息的协议,每个 UDP 段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和 TCP 是很不同的。TCP 状态转换这个图 N 多人都知道,它排除和定位网络或系统故障时大有帮助,但是怎样牢牢地将这张图刻在脑中呢?那么你就一定要对这张图的每一个状态,及转换的过程有深刻的认识,不能只停留在一知半解之中。下面对这张图的 11 种状态详细解析一下,以便加强记忆!不过在这之前,先回顾一下 TCP 建立连接的三次握手过程,以及 关闭连接的四次握手过程。TCP 状态转换图CLOSED:表示初始状态。LISTEN:该状态表示服务器端的某个 SOCK

47、ET 处于监听状态,可以接受连接。SYN_SENT:这个状态与 SYN_RCVD 遥相呼应,当客户端 SOCKET 执行 CONNECT 连接时,它首先发送 SYN 报文,随即进入到了 SYN_SENT 状态,并等待服务端的发送三次握手中的第 2 个报文。SYN_SENT 状态表示客户端已发送SYN 报文。SYN_RCVD: 该状态表示接收到 SYN 报文,在正常情况下,这个状态是服务器端的 SOCKET 在建立 TCP 连接时的三次握手会话过程中的一个中间状态,很短暂。此种状态时,当收到客户端的 ACK 报文后,会进入到 ESTABLISHED状态。ESTABLISHED:表示连接已经建立。

48、FIN_WAIT_1: FIN_WAIT_1 和 FIN_WAIT_2 状态的真正含义都是表示等待对方的 FIN 报文。区别是:FIN_WAIT_1 状态是当 socket 在 ESTABLISHED 状态时,想主动关闭连接,向对方发送了 FIN 报文,此时该socket 进入到 FIN_WAIT_1 状态。FIN_WAIT_2 状态是当对方回应 ACK 后,该 socket 进入到 FIN_WAIT_2 状态,正常情况下,对方应马上回应ACK 报文,所以 FIN_WAIT_1 状态一般较难见到,而 FIN_WAIT_2 状态可用 netstat 看到。FIN_WAIT_2:主动关闭链接的一方

49、,发出 FIN 收到 ACK 以后进入该状态。称之为半连接或半关闭状态。该状态下的 socket 只能接收数据,不能发。TIME_WAIT: 表示收到了对方的 FIN 报文,并发送出了 ACK 报文,等 2MSL 后即可回到 CLOSED 可用状态。如果FIN_WAIT_1 状态下,收到对方同时带 FIN 标志和 ACK 标志的报文时,可以直接进入到 TIME_WAIT 状态,而无须经过 FIN_WAIT_2 状态。CLOSING: 这种状态较特殊,属于一种较罕见的状态。正常情况下,当你发送 FIN 报文后,按理来说是应该先收到(或同时收到)对方的 ACK 报文,再收到对方的 FIN 报文。但是 CLOSING 状态表示你发送 FIN 报文后,并没有收到对方的 ACK 报文,反而却也收到了对方的 FIN 报文。什么情况下会出现此种情况呢?如果双方几乎在同时 close一个 SOCKET 的话,那么就出现了双方同时发送 FIN 报文的情况,也即会出现 CLOSING 状态,表示双方都正在关闭SOCKET 连接。CLOSE_WAIT: 此种状态表示在等待关闭。当对方关闭一个 SOCKET 后发送 FIN

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报