Skip to content

Latest commit

 

History

History
61 lines (34 loc) · 2.38 KB

06-优雅的断开套接字连接.md

File metadata and controls

61 lines (34 loc) · 2.38 KB

优雅的断开套接字连接

1. 基于TCP的半关闭

1. 单方面断开连接带来的问题

Linux的close函数和Windows的closesocket函数意味着完全断开连接。完全断开连接意味着无法传输数据,也无法接收数据;

对于两台正在进行双向通信的主机A、B,如果A发送完数据后就断开了连接,那么A将无法接收B传输的数据---无法调用与接收数据相关的函数。最终主机B传输的、主机A必须接收的数据也销毁了。

为解决上述问题,之关闭一部分数据交换中使用的流的方法出现了。断开一部分连接指的是:可以传输数据但无法接收,或者可以接收但无法传输;

2. 套接字和流

两台主机通过套接字建立连接后进入可交换数据的状态,又称流形成的状态。

一旦两台主机间建立了套接字连接,每个主机就拥有了单独的输入流和输出流。

3. shutdown函数

int shutdown(int sock, int howto);
  • sock:要断开的套接字的文件描述符;
  • howto:传递断开方式信息;
  • 成功返回0,失败返回-1;

第二个参数可取值:

  • SHUT_RD:断开输入流;
  • SHUT_WR:断开输出流;
  • SHUT_RDWR:同时断开I/O流;

4. 为何需要半关闭?

考虑一种情况:

一旦客户端连接到服务器端,服务器端将约定的文件传给客户端,客户端收到文件后发送字符串“Thank you“给服务端。

此时”Thank you“用来模拟客户端还有数据传递给服务器端;

此时程序的实现中的一个难点:如何判断服务端已经将所有文件数据传输完毕?

  • 很简单的想法是约定一个代表文件尾的字符?但是此时文件中不能出现与该约定字符相同的内容!这显然很难办到!

因此考虑EOF表示文件传输结束!客户端通过函数返回值接收EOF,这样可以避免与文件内容冲突!那么如何传递EOF?

  • 服务器端断开输出流向客户端主机传输EOF;

此时服务器端还能接收客户端传输过来的数据。

5. 基于半关闭的文件传输程序

image-20210829091723495

  • 服务器端向客户端传递指定存在的文件!
  • 客户端收到全部内容后传递给客户端”Thank you“;

详细见Code中代码和readme!