基本结构如下图所示:

TCP客户端与服务器函数调用过程及特殊情况

一般而言服务器是被动建立连接,服务器调用socket创建套接字,bind给socket分配具体的ip地址以及端口号,再调用listen函数将刚创建好的socket放入监听队列,之后调用accept等待指定地址(协议)的客户端的连接。

客户端调用socket创建套接字,随后connect来建立连接,客户端的socket的bind操作在connect中隐藏完成。

调用connect之后发生“三次握手”建立TCP连接,随后客户端与服务器之间开始传输数据;

客户端调用close(),发生“四次挥手”撤销TCP连接。

特殊情况:

1、在accept返回之前连接终止

由于系统中断或客户端传入RST,解决办法:再次调用accept即可。因为TCP连接是在内核之中完成的,与accept函数执行并未干系。

2、服务器进程崩溃(子进程终止)

服务器主动发送FIN关闭TCP连接的服务器端,但实际上是服务器的进程都kill掉了,于是客户端继续发送数据,这时候服务器只能响应一个RST,客户端有可能选择忽视掉RST信号,而继续接收数据(例如立刻调用别的读取数据函数),此时就会返回一个错误。

3、服务器主机崩溃(断网)

一般情况下会一直由TCP重传机制来不断重传,直到超出TCP重传定时器所设时限。视为放弃连接,返回服务器不可达错误;

也可以使用keep-alive策略;

keepalive,是在TCP中一个可以检测死连接的机制。

1).如果主机可达,对方就会响应ACK应答,就认为是存活的。

2).如果可达,但应用程序退出,对方就发RST应答,发送TCP撤消连接。

3).如果可达,但应用程序崩溃,对方就发FIN消息。

4).如果对方主机不响应ack, rst,继续发送直到超时,就撤消连接。默认两个小时。

4、服务器主机崩溃后重启

如果不采用keepalive策略,则重启后的主机对客户端发来的数据回报以RST,则跟上述一样,会得到一个错误;

5、服务器主机关机

同;

相关文章:

  • 2021-05-03
  • 2022-01-29
  • 2022-12-23
  • 2022-01-21
  • 2021-04-01
  • 2022-12-23
  • 2021-09-10
猜你喜欢
  • 2021-12-31
  • 2021-11-24
  • 2021-11-17
  • 2021-08-18
  • 2021-08-26
  • 2022-12-23
  • 2021-08-09
相关资源
相似解决方案