首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

TCP客户/服务器异常

TCP客户/服务器异常

1.
服务器进程终止
  假定此时服务器与客户端都已启动,并已建立连接。
  
  
  此时客户端阻塞与fgets调用,并键入一行数据等待下一行,此时杀死服务器子进程
  
  客户端再次输入数据之后:
  
  
  整个过程图解如下
  
  客户端接收到FIN(即处于CLOSE_WAIT状态),说明服务器已经关闭了连接,但是服务器并没有告知客户端TCP服务器已经终止。于是客户端继续发送数据,服务器响应一个RST,可以抓包看到:
  192.168.197.5
192.168.197.10 Src=41839,Dst=9877,.AP...,S=1333764517

  192.168.197.10
192.168.197.5
Src=9877 Dst=41839,...R..,S=2138602188

  此问题说明了:客户端不能单纯阻塞在套接字和标准输入某个特定的源的输入(比如阻塞与fgets,但是不阻塞与socket),而应该阻塞在其中任何一个源的输入上,于是引入了selectpoll,这是后话。
  2.
服务器主机崩溃
  首先服务器启动进程,客户端打开连接,并输入一行数据,然后让主机崩溃(虚拟机里面在点poweroff
  
  可以看到整个过程大概为15分钟,这也太夸张了!!原因是客户端发送完数据之后,
  一直阻塞与read(从服务器到客户端)调用,然后一直重传,直到最后超时,客户最终会发现服务器主机已崩溃或主机不可达。解决的方法就是自己写一个read函数然后设置超时,或者加一个SO_KEEPALIVE选项。
  3.
服务器主机崩溃后重启
  这个实验也挺有意思,首先建立好连接,和上面一样,先输入一行,然后再输一行,
  这时把主机崩溃了,再重启它。
  
  抓包的情况看看:
  192.168.197.10
192.168.197.5

Src=9877,Dst=41848,...R..,S=3100751727
  可以看到服务器此时并没有启动服务器进程,当它重启之后收到了一个请求的连接,
  于是对于来自客户的数据分节响应一个RST,客户阻塞与read调用,收到了这个RST之后便返回ECONNRESET错误。
  4.
服务器关机
  这里指的是正常关机,因为Unix系统关机时,会发送SIGTERMSIGKILL信号,
  SIGTREM可能忽略,但是SIGKILL信号不能忽略,于是服务器将由SIGKILL终止,当服务器子进程终止时,第一种情况(服务器进程终止)再次重演。
继承事业,薪火相传
返回列表