从TCP协议到TCP通信的各种异常现象和分析(上)

  • 时间:
  • 浏览:15
  • 来源:小天博客 - 专注共享小乖博客资源

不多不多人总着实学习TCP/IP协议没那此用,着实日常编程开发只才能 知道socket接口为什么在么在在么在用就都才能 了。可能性当当我们定位过线上难题就会知道,实际上并不这么 。可能性应用在局域网内,且设备一切正常的状况下可能性着实这么 ,但可能性一旦再次再次出现诸如中间交换机不稳定、物理服务器宕机可能性其它异常状况时,此时引起的难题可能性只在等待在套接字接口的理解层面将无法处里。为什么在么在让,深入理解TCP/IP协议,对当当我们分析异常难题有很大的帮助。

下图是网络通信中常见的架构,也只是CS架构。其中应用程序池池包括两要素,分别为客户端(Client)和服务端(Server)。当然,实际的环境才能 繁杂的多,在客户端和服务端之间可能性有多种不同种类和数量的设备,那此设备总要增加网络通信的繁杂性。自然,也会增加应用程序池池开发容错的繁杂性。

图1 基本架构

TCP的基本流程

在分析异常状况时会,当当我们先回忆一下TCP协议的基本逻辑。在客户端和服务端才能收发数据时会首先必需建立连接。连接的建立在协议层面也是通过收发数据包完成,只不过在用户层面只是客户端调用了有俩个connect函数。连接的过程俗称“三次握手”,具体流程如图2所示。

图2 TCP的三次握手流程

TCP连接的断开也是比较繁杂的,才能 经过所谓的“四次挥手”的流程。其由于着是可能性TCP是双工通信,分别才能 从客户端和服务端2侧断开连接。

图3 TCP的四次挥手

另外有俩个比较重要的内容是TCP协议的状况转换,理解了你这一 内容,当当我们才能清楚再次再次出现各种异常状况下数据包的内容。

图4 TCP状况转换图

本文只是简单回忆一下TCP的基本流程,删剪的内容都才能 参考本号时会的文章《从TCP到Socket,彻底理解网络编程是为什么在么在在么在回事》

异常状况分析

了解了TCP的基本流程时会,当当我们再看一下各种异常状况。那此异常状况才是当我们也有后续处里难题的时会的关键。了解了那此异常状况及原理,中间处里难题才能游刃有余。

1. 试图与有俩个不趋于稳定的端口建立连接(主机正常)

这里的不趋于稳定的端口是趋于稳定服务器端这么 应用程序池池监听在该端口。当当我们的客户端就调用connect,试图与其建立连接。这总要趋于稳定那此呢?

你这一 状况下当我们也有客户端通常会收到如下异常内容:

  1. [Errno 111] Connection refused(连接拒绝) 

具体含义都才能 查一下Linux的相关手册,可能性用搜索引擎搜索一下。试想一下,服务端另俩个就这么 应用程序池池监听在你这一 接口,为什么在么在让在服务端是无法完成连接的建立过程的。当当我们参考‘三次握手’的流程都才能 知道当客户端的SYNC包到达服务端时,TCP协议这么 找到监听的套接字,就会向客户端发送有俩个错误的报文,告诉客户端产生了错误。而该错误报文只是有俩个中含RST的报文。你这一 异常状况也很容易模拟,当当我们只才能 写有俩个小应用程序池池,连接服务器上这么 监听的端口即可。如下是通过wireshark捕获的数据包,都才能 都看红色要素的RST报文。

图5 数据包截图

继续深入理解一下,在操作系统层面,TCP的服务端实际上只是从网卡的寄存器中读取数据,为什么在么在让进行解析。对于TCP自然会解溶解目的端口你这一 关键信息,为什么在么在让根据你这一 信息查看有这么 另俩个的套接字。你这一 套接字是那此呢?在用户层面是有俩个文件句柄,但在内核中实际是有俩个数据社会形态,中间记录了不多不多信息。你这一 数据社会形态存储在有俩个哈希表中,通过函数__inet_lookup_skb(net/inet_hashtables.h)都才能 实现对该数据社会形态的查找。对于上述状况,自然无法找到该套接字,为什么在么在让TCP服务端会进行错误处里,处里的土方法只是给客户端发送有俩个RST(通过函数tcp_v4_send_reset进行发送)。

2. 试图与有俩个某端口建立连接但该主机可能性宕机(主机宕机)

这也是并也有比较常见的状况,当某台服务器主机宕机了,而客户端并我想知道,仍然尝试去与其建立连接。你这一 场景也是分为2种状况的,并也有是时会宕机,另外并也有是宕机了很长时间。为那此要分这2种状况?

这主要根ARP协议有关系,ARP会在本地缓存失效,TCP客户端就无法想目的服务端发送数据包了。

  1. (192.168.1.3000) 趋于稳定 08:00:27:1a:7a:0a [ether] 在 eth0 

了解了上述状况,当当我们分析一下时会宕机的状况,此时客户端是都才能 向服务端发送数据包的。为什么在么在让可能性服务器宕机,为什么在么在让不让给客户端发送任何回复。

图6 数据包截图

可能性客户端并我想知道服务端宕机,为什么在么在让会重复发送SYNC数据包,如图6所示,都才能 都看客户端每隔几秒会向服务端发送有俩个SYNC数据包。这中间具体的时间是跟TCP协议相关的,具体时间不同的操作系统实现可能性稍有不同。

3. 建立连接时,服务器应用被阻塞(可能性僵死)

还有并也有状况是在客户端建立连接的过程中服务端应用趋于稳定僵死状况,你这一 状况在实际中也会老要再次再次出现(当当我们假设仅仅应用应用程序池池僵死,而内核这么 僵死)。此总要再次再次出现那此状况?TCP的三次不是都才能 完成?客户端不是都才能 收发数据?

在用户层面当当我们知道,服务端通过accept接口返回有俩个新的套接字,这时就都才能 和客户端进行数据往来了。也只是在用户层面来说,accept返回结果说明3次握手完成了,为什么在么在让accept会被阻塞。在当当我们假设的状况下,着实就大概应用应用程序池池无法进行accept操作了。

可能性想彻底理解中间当当我们假设的难题,才能 理解两点,某些是accept函数具体做了那此,另外某些是TCP三次握手的本质。

当当我们先试着理解第某些,accept会通过软中断陷入内核中,最终会调用tcp协议的inet_csk_accept函数,该函数会从队列中查找不是有趋于稳定ESTABLISHED状况的套接字。可能性有则返回该套接字,为什么在么在让阻塞当前应用程序池池。也只是说这里只是有俩个查询的过程,并不参与三次握手的任何逻辑。

三次握手的本质是那此呢?实际上只是客户端与服务端有俩个不断交流的过程,而你这一 交流过程只是通过五个数据包完成的。而你这一 数据包的发送和处里实际上也有在内核中完成的。对于TCP的服务端来说,当它收到SYNC数据包时,就会创建有俩个套接字的数据社会形态并给客户端回复ACK,再次收到客户端的ACK总要将套接字数据社会形态的状况转换为ESTABLISHED,并将其发送就绪队列中。而这整个过程跟应用应用程序池池这么 半毛钱的关系。

当中间套接字加入就绪队列时,accept函数就被唤醒了,为什么在么在让就都才能 获得新的套接字并返回。但当当我们回过头来看一下,在accept返回时会,着实三次握手可能性完成,也只是连接可能性建立了。

另外有俩个是可能性accept这么 返回,客户端不是都才能 发送数据?答案是都才能 的。可能性数据的发送和接受也有在内核态进行的。客户端发送数据后,服务端的网卡会先接收,为什么在么在让通过中断通知IP层,再上传到TCP层。TCP层根据目的端口和地址将数据存入关联的缓冲区。可能性此时应用应用程序池池有读操作(累似 read或recv),这么 数据会从内核态的缓冲区拷贝到用户态的缓存。为什么在么在让,数据会老要在内核态的缓冲区中。总的来说,TCP的客户端不是都才能 发送数据与服务端应用程序池池不是工作这么 任何关系。

当然,可能性是整个机器都卡死了,那只是另外并也有状况了。你这一 状况就当当我们时会分析的第2种状况老要了。可能性,可能性机器删剪卡死,TCP服务端无法接受任何消息,自然也无法给客户端发送任何应答报文。

总结

今天当当我们主要介绍了连接建立过程中的各种异常状况,还有另外并也有状况是在数据的传输过程中。比如传输过程中服务器老要掉电,可能性应用程序池池crash等,后续当当我们将删剪那此异常状况下在协议层的表现。

接下篇《从TCP协议到TCP通信的各种异常难题和分析(下)》

【编辑推荐】

【责任编辑:

赵宁宁

TEL:(010)684763006】



点赞 0