预备知识
再谈端口号
传输层要想将数据进行交给应用层,本质是将数据交给用户层的进程,如何确定将数据进行交给哪个进程进行处理,在我们前面进行写TCP和UDP网络协议的时候我们知道在进行通信的准备工作时,有一个步骤时需要进行绑定端口号,其实应用层通过bind进行绑定端口号其实就是将即将进程和端口号进行插入到哈希表中建立映射关系,这样传输层要将数据进行交给应用层的某个进程,直接通过端口号就可以直接进行确定.
端口号的划分
在进行写基于UDP、TCP的网络通信程序中,我们进行绑定的端口号的类型都是uint_16的也就是16位的无符号整数,正好是0~65535,这就是所有端口号的范围
- 0 - 1023: 知名端口号, HTTP, FTP, SSH等这些广为使用的应用层协议, 他们的端口号都是固定的.
- 1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作系统从这个范围分配的.
认识知名端口号
- ssh服务器, 使用22端口
- ftp服务器, 使用21端口
- telnet服务器, 使用23端口
- http服务器, 使用80端口
- https服务器, 使用443
执行下面的命令, 可以看到知名端口号
cat /etc/services
思考:
一个进程可以绑定多个端口号吗??一个端口号可以被多个进程进行绑定吗??
一个进程是可以进行绑定多个端口号的,但是一个端口号是不可以进行被多个线程进行绑定的,假如说一个线程进行绑定了多个端口号,当传输层收到数据后进行将数据进行处理结束通过端口号是可以找到并交给指定进程进行处理,但是如果一个端口号被多个进程进行绑定,无法通过端口号进行找到指定进程进行处理数据.所以我们自己写一个程序使用端口号时, 要避开这些知名端口号.防止因为抢占端口号造成某个服务器不能正常工作.
netstat
netstat是一个用来查看网络状态的重要工具.
语法:netstat [选项]
功能:查看网络状态
常用选项:
n 拒绝显示别名,能显示数字的全部转化成数字
l 仅列出有在 Listen (监听) 的服務状态
p 显示建立相关链接的程序名
t (tcp)仅显示tcp相关选项
u (udp)仅显示udp相关选项
a (all)显示所有选项,默认不显示LISTEN相关
pidof
在查看服务器的进程id时非常方便.
语法:pidof [进程名]
功能:通过进程名, 查看进程id
UDP
UDP的协议段格式
UDP是如何进行解包和分用的?
首先进行回想一下,什么是解包?什么是分用?解包就是将报头和有效载荷进行分离的操作,分用是协议在传输层进行将数据进行处理后,进行交给上层的过程.
从UDP的结构可以看到,UDP采用了固定报头长度的方法,方便后续进行将报头和有效载荷进行分离,这就完成了解包的过程;报头中有目的端口号,通过目的端口号就能够找到上层特定进程,将有效载荷交给特定进程,完成了数据的分用.
如何理解报头?
上面的两个结构体是等价的,只不过是下面的那个是位段的形式
Linux内核就是用C语言写的,所谓的报头就是一种结构化数据的对象.
报头就是通过malloc进行申请一段空间,通过将应用层的数据填充到这段空间中的剩下的位置.
UDP的特点
UDP传输的过程类似于寄信.
- 无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接;
- 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层 返回任何错误信息;
- 面向数据报: 不能够灵活的控制读写数据的次数和数量
如何进行理解面向数据报?
简单的说就是,通过UDP进行传输的消息是不能够进行拆分的,应用层交给UDP多长的报文, UDP原样发送, 既不会拆分, 也不会合并
用UDP传输100个字节的数据: 如果发送端调用一次sendto, 发送100个字节, 那么接收端也必须调用对应的一次recvfrom, 接收100个 字节; 而不能循环调用10次recvfrom, 每次接收10个字节;
UDP的缓冲区
UDP是没有严格意义上的发送缓冲区,调用sendto会直接交给内核, 由内核将数据传给网络层协议进行后 续的传输动作; UDP具有接收缓冲区. 但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致; 如果 缓冲区满了, 再到达的UDP数据就会被丢弃;假设UDP正在应用层进行分析处理也需要一定的缓冲区进行数据的暂存,要不然丢包概率太高。这里的丢包就是UDP协议中的不可靠的体现。
这种既能读又能写的方式称为全双工。
UDP的坑
UDP报头中用于标定UDP长度的只有16位,也就是说包括报头,通过UDP进行传输的数据最大是64KB,如果超过64KB数据由于接收缓冲区接收不了,会直接被丢弃。所以应用层需要将数据进行打散到64KB以下,否则会进行发送失败。
TCP
TCP的协议段格式
TCP是如何进行解包和分用的?
TCP协议是有20个字节标准长度的,通过着20个字节的标准长度进行读取,然后将这20个将其转换成结构化的数据,从结构化数据中进行提取4位首部长度,根据计算得到的报头长度,从 TCP 段的起始位置截取相应长度的数据作为报头。从报头结束位置开始到 TCP 段末尾的所有数据就是有效载荷。
但是4位首部长度的二进制位全是1时,也才15,光报头的标准长度就20个字节了,怎么可能是用4位首部长度来进行表示TCP报头+有效载荷的长度呢?? 其实不然,4位首部长度的单位是4字节,也就是说4位首部长度可以表示的范围是[0,60].
和文件系统进行结合起来理解分用
我们在收到一个报文,是如何找到曾经bind绑定的特定的port进程的!网络协议栈和文件是什么关系??
OS很多情况下是需要我们进行快速定位一个进程的,这是如何进行做到的呢??通过Hash进行将进程的PCB和端口号建立映射关系,然后PCB中是存在指向file_struct结构的指针的,从中进行申请文件描述符进行返回到应用层,然后通过struct file中的读写函数指针进行指向传输层进行读写,传输层将数据进行处理后放到缓冲区中,然后struct file中存在指向缓冲区的指针,从缓冲区中进行读取数据.
如何理解TCP中的报头??
TCP的缓冲区
TCP也是全双工的,TCP称为传输控制协议,之所以称为传输控制协议的原因是因为存在发送缓冲区,当将要进行将发送缓冲区中的数据进行发送到对方的接收缓冲区中时,假如对方的接收缓冲区已经满了,数据就不在进行发送,而是存在于接收缓冲区中,通过这样的方式就可以在一定程度上控制数据的发送,所以TCP又称为传输控制协议.
TCP的可靠性&&提高传输效率
其实内存和外设之间既有自己的通信,又有自己的协议,内存和外设之间用的"线"称为IO总线,内存和CPU之间进行连接的时候,也是通过"线"进行的,称为系统总线.
内存和外设之间既然是存在通信的,是否还需要进行考虑可靠性问题呢? 答案是不需要的,为什么呢?因为距离很近,一般不会出现不可靠性的问题.
但是两台主机之间的通信由于距离问题,就会出现数据丢包等不可靠性的问题.TCP又是可靠性进行传输的,所以说TCP内部为了保证可靠性需要进行确保数据可靠性的策略.
常见的不可靠数据
保证可靠性需要进行处理的非可靠性数据,例如丢包、乱序、校验错误、重复........等等一系列的问题.
确认应答机制
序列号和反序列号
数据在从应用层进行拷贝到传输层中的发送缓冲区中时,就天然的有了序号.
当主机A进行和主机B进行通信,主机A向主机B进行发送数据,由于主机A和主机B的距离问题,主机A无法确定进行发送是数据是否被主机B收到,只有主机A收到主机B的应答才是确保数据已经被主机B收到了,反之,则认为数据没有被对方主机接收到.
TCP是如何实现TCP的应答机制的?
在传输层客户端和服务端的地位是相同的,他们进行通信的工作方式也是相同的,以一方为例进行分析问题,以client→server为例(server→client也是相同的流程)
当客户端进行批量发送一些数据时,假如这些批量的数据中的某一条数据丢失,造成丢包现象了,客户端根据服务端进行反应的丢包情况进行对发送的数据进行查找,这就需要每一个进行发送的数据都有一个标号用于对数据的管理.由于TCP是全双工的,所以说还需要通过另一个字段进行存储应答的相关数据.
TCP确认应答的方式
由于进行数据传输一般都是批量进行传输的,应答机制都是返回收到的数据的最后一个序列号,表示该序列号之前的数据我都已经收到了
窗口号大小
通过TCP在进行传输数据的过程中,数据的传输速率需要进行控制的,当传输速率过高时,接收缓冲区中被数据塞满后,在向接收缓冲区中进行数据的写入时,就会容易出现数据丢失严重,反之,当传输速率过慢时,另一端会较长时间处于阻塞状态,所以 tcp在进行在进行发送数据的时候,快了不行,慢了也不行,需要通过找到合适的速率进行,tcp是如何进行得知对方缓冲区中的剩余空间的大小的呢??
TCP协议的报头中有一个字段是16位窗口大小,这个字段用于存储自己接收缓冲区的剩余空间的大小,在通过数据传输通信的过程中,将数据进行发送给对方,对方就得知了我的接收缓冲区中的剩余空间大小,相当于进行交换了接收能力.
超时重传机制
TCP进行解决丢包的机制就是重传.
发送数据方是如何进行确定数据丢包的?
发送数据方没有接收到来自数据接收方的应答,就认为刚刚进行发送是数据已经丢包了.没有接收到应答的方式有下面两种,无论是哪种情况,发送端进行发送出去的数据,我们并不想直接进行一处,而是暂存于缓冲区,用于应对丢包问题.
- 数据在在进行向目的主机进行发送的过程中发生数据丢包
当数据发送方没有收到的接收方的应答超过一段时间时,触发超市重传机制,数据发送方进行重新将刚刚进行发送的数据进行重新发送.直至数据接收方收到数据并接收到来自接收方的应答.超时时间并不是固定的,而是根据网络情况进行确定的.
- 发送方已经将数据进行交给接收方了,接收方在进行发送应答的数据,应答的数据在进行通信的过程中丢失了
当接收方已经收到的发送方的数据,但是由于应答丢失造成的超时重传机制,导致相同的数据重复,直接通过序号进行去重.
标记位
ACK(acknowledgment)
ACK用来表示该报文段是对上一个报文的确认,当ACK=1时表示上一个报文有效,用于告诉对方我已经收到你发来的消息了。
TCP报文也是有类型的,服务器会受到各种各样的报文,服务器需要根据不同的报文,进行不同方式的处理,在三次握手和四次挥手中,除了首个建立连接报文外,所有报文均需设置ACK=1,代表携带确认号.
SYN(Synchronize)
SYN是同步序列编号,用于初始化一个连接,告诉对方我要进行建立连接了,是从该同步序列编号开始的。
FIN(Finish)
fin表示结束连接,用于告诉对方我已经没有要发送的数据了,想要进行结束连接。
RST(Reset)
立即中断连接并释放资源。表示发生异常或错误,需要强制断开连接。
- 当连接出错,比如访问了不存在的端口时,服务端会发送一个 RST 报文 拒绝连接。
- 应用程序崩溃后发送 RST 强制中断连接。
通过三次握手和四次挥手进行建立链接和销毁链接的过程并不是一帆风顺的,是有可能会出现失败的,就算建立连接成功,在进行通信的过程中也是有可能出现单方连接出现问题,导致有一方连接已经不存在了,但是另一方认为连接依然存在的问题
PSH (push)
告诉接收方应该立即将数据交给上层应用,而不是缓存。
当对方的接收缓冲区满了后,对方始终还未进行从接收缓冲区中进行读取数据,发送方设置PSH=1,催促接收方立即将数据交给应用层处理。
URG(Urgent)
当前数据报中存在紧急数据,需要优先处理。
数据对于接收方而言,乱序本身就是数据不可靠的体现,通过报文对数据进行排序,保证数据的按序到达.但是如果发生特殊情况,某些特殊的数字需要进行插队,这时候就需要将这类数据的报头中的URG置为1,表示这是要被进行特殊处理的数据,如何进行找到这个数据呢?16位的紧急指针中存放的是数据从起始地址开始的偏移量,我们只能通过这个紧急指针拿到这个紧急数据的起始地址,
怎么进行得知这个数据有多长呢??
规定:一个字节.
连接管理机制
在正常情况下, TCP要经过三次握手建立连接, 四次挥手断开连接
三次握手
误区 :
在三次握手和四次挥手时进行通信都是以报头作为数据进行传输的,并不是以标记位进行的。
连接结构体是可靠性的基础,三次握手是建立连接结构体的基础
三次握手并不是站在上帝视角,而是站在某一服务器的视角
怎么进行理解上面这句话呢,对于client来说,首先通过发送报头,并将报头中的SYN标记位进行置1,对于client来说是没有上帝视角的,当想要进行第一次握手时,将报头进行发送过去时,就认为自己已经第一次握手成功了,并不考虑对方是否收到。这是因为我们有超时重传机制,我们根本不担心前两次的握手会丢包,一旦没有收到对方的回应,直接进行触发超时重传机制即可,往往我们最担心的是第三次握手没有,因为此三次握手是没有应答的,但是这是有策略进行解决的,[SYN_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文, 就进入ESTABLISHED状态, 可以进行 读写数据了,当服务器的状态没有变为 ESTABLISHED,我们认为客户端进行向服务端的应答丢失了,需要进行重新应答。
为什么TCP的连接管理机制是通过三次握手进行建立连接,四次挥手进行断开连接?
SYN洪水攻击
在SYN洪水攻击中,攻击者发送大量伪造的SYN包,通常使用虚假的源IP地址,目的是耗尽服务器的资源,攻击者使用虚假IP地址发送SYN包,服务器将SYN-ACK发送至该伪造IP。由于攻击者无法控制伪造IP对应的真实主机,无法截获SYN-ACK响应,因此无法生成正确的ACK确认。
假如通过一次握手即可进行建立连接,客户端恶意进行频繁建立连接,会导致服务器的资源耗尽,这种方式称为SYN洪水,假如通过两次握手即可建立连接,也是和上述一次握手同理,服务器进行接收到客户端的连接后进行应答后就进行分配资源,本质上和一次握手相同
通过三次握手,进行前两次进行握手成功后服务器并不会进行分配完整的资源,而是分配半开连接资源,只有通过客户端三次握手回应时,才会进行分配完整的资源,从而实现了最大程度实现了抵抗SYN洪水攻击的机制。
四次挥手
主动进行断开连接的人的一方最终的状态是TIME_WAIT,time_wait状态表示四次挥手已经完成,但是需要进行维持一段时间的time_wait 状态,需要进行等待一段时间,为什么要进行等待一段时间呢??
①保证最后一个ACK应答尽可能被对方收到 ②双方在进行断开连接的时候,网络中还存在滞留的报文,保证滞留的报文消散。
服务器有时候可以立即重启,但是有时候无法进行立即重启,就是因为服务器的这个端口处于time_wait状态,导致进行bind绑定失败。
进行等待的时间是多少才合适呢?
MSL是TCP报文的最大生存时间, 因此TIME_WAIT持续存在2MSL的话 就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失(否则服务器立刻重启, 可能会收到 来自上一个进程的迟到的数据, 但是这种数据很可能是错误的); 同时也是在理论上保证最后一个报文可靠到达(假设最后一个ACK丢失, 那么服务器会再重发一个FIN. 这 时虽然客户端的进程不在了, 但是TCP连接还在, 仍然可以重发LAST_ACK);
被动的断开连接的一方,经过两次挥手后会进入到close_wait状态,如果我们的服务器出现大量的close_wait是出现什么状况了呢?
①服务器有BUG,没有进行将使用完的文件描述符进行关闭 ②服务器有压力,一直在进行推动消息给client,导致没有时间进行close文件描述符。
流量控制
接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送, 就会造成丢包, 继而引起丢包重传等等一系列连锁反应. 因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制
滑动窗口
我们之前在进行学习TCP报头中的16位窗口大小时,我们知道16位窗口大小是为了得知对方接收缓冲区的大小,用于交换对方的缓冲能力,更好的平衡发送和接收之间的关系,那这个十六位窗口大小进行运作的原理是怎样的呢?
首先进行进行思考,发送方和接收方怎么在第一次就知道对方的接收能力的呢?
在进行第一次通信之前肯定是已经进行建立连接了的,建立连接就证明三次握手已经成功,已经进行了交换了窗口大小。这里我们先认为滑动窗口用于进行维护对方的接收能力的大小。
建模1:
如何进行看待滑动窗口的问题
win_start =ACK_SEQ------代表下一次进行发送是位置
win_end =win_start+tcp_win-----代表下一次进行发送的位置+上窗口大小
窗口一定会向右移动吗?会不会向左移动呢?
窗口是会向右进行移动的,因为当接收方将接收缓冲区中的数据进行确认后,导致win_start指针右移,导致窗口向右进行移动,但是并不是一定会向右进行移动,当接收方一直不进行确认数据时,窗口是可能不发生移动的。但是无论如何窗口是不可能向左进行移动的。
窗口的大小一定会一直不变吗?会变大吗?会变小吗?变化的依据是什么?
窗口的大小是有可能不发生变化的,当接收方一直没有进行读取缓冲区中的数据,当接收方进行确认应答,但是没有将数据进行读取,会使得win_start指针向右移动,而win_end指针并未移动,造成窗口减小;当接收方将缓冲区中的数据进行读取,没有将发送方新发送的数据进行确认,就会导致win_end指针向后进行移动,造成窗口变大。
收到应答确认的时候,如果不是最左侧发送的报文确认,而是中间的、结尾的怎么办?要滑动吗?
出现上述情况的原因肯定是发生了丢包,丢包的情况又有两种
假如数据没有丢失,是接收方的应答丢失了,代表前面的数据我已经收到了,不需要进行超时重传
假如是数据真的发生丢失了,接收方根据应答机制会进行应答接收到的连续的序号的的最后一个,收到三个以上的的相同应答时,进行触发超时重传机制。
一直进行向右滑动,如果空间不够了怎么办?
发送缓冲区被内核组成成了环形结构
建模2:
流量控制
接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送, 就会造成丢包, 继而引起丢包重传等等一系列连锁反应. 因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control);
拥塞控制
网络拥塞
通过滑动窗口我们可以进行解决数据的批量高效和可靠性, 但是如果在刚开始阶段就发送大量的数据, 仍然可能引发问题. 因为网络上有很多的计算机, 可能当前的网络状态就已经比较拥堵. 在不清楚当前网络状态下, 贸然发送大量的数据, 是很有可能引起雪上加霜的.
如何进行理解上述表达呢?
以网络中的某两台服务器进行通信为例,当客户端向服务端进行假如发送了1000个报文数据,通过网络进行通信,有可能会出现丢包,丢包的情况会分成下面两种情况
情况一:只丢失了极少部分的报文
比如1000报文中丢失了三两个,客户端认为这是正常丢包情况,根据确认应答机制和超时重传机制进行重传,这是没有任何问题的。
情况二:几乎所有的报文全部丢失
但是如果几乎进行发送的1000个报头全部丢失了,这就表明可能是网络出现问题了,但是如果我们还进行通过确认应答机制和超时重传机制进行重传,进行重传数据的并不只是某两台进行通信的机器,而是网络中所有的机器,这就会使得网络更加的瘫痪。
慢启动
为了解决上述问题,并且预防这个问题再进行发生,采取慢启动的策略,先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据。
此处引入一个概念程为拥塞窗口 发送开始的时候, 定义拥塞窗口大小为1; 每次收到一个ACK应答, 拥塞窗口加1; 每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗口。
首先需要进行明确,网络是有一定程度的自恢复能力的,慢启动的策略是,先进行指数增长,为了不增长的那么快, 因此不能使拥塞窗口单纯的加倍. 此处引入一个叫做慢启动的阈值 当拥塞窗口超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长,在进行线性增长的时候出现网络拥塞时,进行调整新的阈值。
进行指数增长是为了尽快恢复TCP进行通信的常规通信,通过线性增长为了尽可能避免网络拥塞。
也就是说进行发送数据,不但要考虑对方的承受能力,还能考虑网络的承受能力,所以说在这里进行完善滑动窗口的概念,滑动窗口是用于表述自己的接收能力,但是承受能力不仅仅需要看自己的接收能力,还要看网络的承受能力
因此:
滑动窗口的大小=min(拥塞窗口,窗口大小(自己的接收能力))
可靠性和效率的双重保障
若无拥塞控制,丢包会触发发送端不断重传,进一步加剧网络负载,形成恶性循环。通过快速重传和快速恢复等机制,TCP能在丢包时快速调整速率,恢复网络稳定。
假设网络中有足够的带宽,但如果发送方不根据网络状况调整速率,可能会导致数据包在中间节点堆积,产生延迟,甚至丢包。这样即使最终数据到达,但延迟过高,影响整体效率。此外,如果发送方过于保守,比如一直保持很低的发送速率,虽然避免了拥塞,却未能充分利用可用带宽,导致资源闲置,同样效率低下。
延迟应答
延时应答的必要性
如果接收数据的主机立刻返回ACK应答, 这时候返回的窗口可能比较小. 假设接收端缓冲区为1M. 一次收到了500K的数据; 如果立刻应答, 返回的窗口就是500K; 但实际上可能处理端处理的速度很快, 10ms之内就把500K数据从缓冲区消费掉了; 在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来; 如果接收端稍微等一会再应答, 比如等待200ms再应答, 那么这个时候返回的窗口大小就是1M;
窗口越大, 网络吞吐量就越大, 传输效率就越高. 我们的目标是在保证网络不拥塞的情况下尽量提高传输效率;
延时应答的策略
- 数量限制: 每隔N个包就应答一次;
- 时间限制: 超过最大延迟时间就应答一次;
具体的数量和超时时间, 依操作系统不同也有差异; 一般N取2, 超时时间取200ms;
捎带应答
捎带应答是指在一个数据包中同时携带数据和确认信息,而不是单独发送一个ACK包。这样可以减少网络中的包数量,提高带宽利用率。比如,当客户端发送数据给服务器时,服务器如果有数据要回复,就可以把ACK信息附带在数据包中一起发送回去,而不是单独发一个ACK包。
TCP的衍生问题
面向字节流
数据像水流一样连续传输,没有固定的边界。发送方多次写入的数据可能会被接收方一次读取,或者一次写入的数据被分成多次读取,用write时, 数据会先写入发送缓冲区中; 如果发送的字节数太长, 会被拆分成多个TCP的数据包发出; 如果发送的字节数太短, 就会先在缓冲区里等待, 等到缓冲区长度差不多了, 或者其他合适的时机发送出去。
粘包问题
应用层调用接口函数向网络中进行发送数据,并不是将数据直接进行丢到网络中,而是交给传输层进行处理,假设传输层使用的协议是的TCP,接收缓冲区中的数据是连续的字节流,应用层无法直接感知原始发送的“消息”边界。
TCP是面向字节流的协议,数据在传输层没有消息边界,所以发送方多次send的数据可能在接收方一次recv中收到,或者一次send的数据被拆分成多次接收。这就是所谓的粘包问题,即多个数据包被粘在一起,或者一个包被拆开。
粘包问题需要在应用层进行定制协议解决,开发者需手动处理消息边界(下面是几种常见的处理边界的方法)
固定长度:每条消息长度固定(如512字节)。
分隔符:通过特殊字符(如
\r\n
)分割消息。长度前缀:在消息头部添加长度字段(如4字节表示消息体长度)。
TCP异常情况
- 进程挂掉:进程终止会释放文件描述符, 仍然可以发送FIN. 和正常关闭没有什么区别.
- 直接重启:首先把进程先进行关闭(之前还需要进行四次挥手)和进程直接挂掉没有任何区别
- 拔网线:客户端无法向服务端进行挥手,服务器有保活策略,定期进行询问,如果没有应答,直接按照进程挂掉处理。