计网 Socket编程

521 阅读2分钟

Socket是什么?

Socket是一种编程模型。 从编程的角度来看,客户端将数据发送给在客户端侧的Socket 对象,然后客户端侧的 Socket 对象将数据发送给服务端侧的 Socket 对象。 Socket 对象负责提供通信能力,并处理底层的 TCP 连接/UDP 连接。

Socket 还是一种文件,准确来说是一种双向管道文件。双向管道文件连接的程序是对等的,都可以作为输入和输出。

当一个客户端连接到服务端的时候,操作系统就会创建一个客户端 Socket 的文件。然后操作系统将这个文件的文件描述符写入服务端程序创建的服务端 Socket 文件中。服务端 Socket 文件,是一个管道文件。如果读取这个文件的内容,就相当于从管道中取走了一个客户端文件描述符。

客户端 Socket 是一个双向管道,操作系统将客户端传来的数据写入这个管道,也将线程写入管道的数据发送到客户端。

命令式的Socket

在Linux中,select和poll都是命令式地发现socket文件的变动。他们会在发现I/O操作的时候就去扫描所有的socket文件,去发现是谁接受了信息。

通过一个线程来响应多个客户端连接,也被称为I/O多路复用

响应式

实际上,在Linux中使用了epoll来实现一种响应式的socket操作。在线程和客户端socket文件中间,存在一个中间的观察者。当socket文件发生变动时,会被中间观察者发现,然后中间观察者再通知线程进行处理。

显然,中间观察者最适合由操作系统来担当。在这中间,我们通常使用红黑树来作为数据结构。 这涉及到两个核心需求:

  1. 让线程可以注册自己关心的消息类型。
  2. Socket 发生变化(读写等)时,能够快速地判断是哪个线程需要知道这个消息。