【发布时间】:2016-06-24 22:03:13
【问题描述】:
我知道一台服务器通常会打开一个端口并监听它。
今天得知类Unix系统中有一个函数select。使用select,我们可以监听多套接字。
我无法想象我们需要使用select 的情况。如果我们有两个套接字,这意味着我们正在监听两个端口,对吧?所以我有一个问题:
什么样的服务器会打开多个端口但接收和处理相同类型的请求?
【问题讨论】:
我知道一台服务器通常会打开一个端口并监听它。
今天得知类Unix系统中有一个函数select。使用select,我们可以监听多套接字。
我无法想象我们需要使用select 的情况。如果我们有两个套接字,这意味着我们正在监听两个端口,对吧?所以我有一个问题:
什么样的服务器会打开多个端口但接收和处理相同类型的请求?
【问题讨论】:
使用select 有助于处理多个套接字上的读取和写入。它不必是多个 server 套接字。最典型的用途是多路复用大量 client 套接字。
您有一台带有一个侦听套接字的服务器。每次accept 连接时,都会将新的客户端套接字添加到多路复用池中。 select 然后在任何这些套接字中的任何一个具有可供读取的数据时返回。最大的胜利是您使用一个线程完成所有这些操作。
【讨论】:
对于您在侦听(服务器)套接字上accepted 的每个连接,您还可以获得套接字。
selecting 在这些(客户端)套接字和服务器 socket(可读 => 新连接)之间,您可以高效地编写聊天服务器等应用程序。
【讨论】:
嗯...记住端口和套接字之间的区别。
“端口”就像电话号码。但是一个电话号码可以处理任意数量的“电话”!
因此,“套接字”表示单个电话呼叫:此服务器和特定客户端之间的当前活动连接。根据定义,每个连接“发生在特定端口上”,但可能同时存在任意数量的连接。
(“接听”操作对应:拿起电话。)
那么,select() 为您带来的是一次监控任意数量的套接字的能力。它检查所有套接字,等待 (如果需要) 等待其中任何一个发生某些事情,然后返回 一个 消息给您。现在,您的服务器的设计变成了“一个简单的循环”。无论您正在收听多少个套接字,也无论其中有多少个有消息等待,select() 都会一次将消息返回给您。
基本上是这样的情况,“那里的每台服务器都会在其核心使用select() 循环,除非有一个非常好的理由不。
【讨论】:
看这里:
编写网络服务器的一种传统方法是使用主 accept() 上的服务器块,等待连接。一旦连接 进来,服务器fork()s,子进程处理连接 并且主服务器能够处理新的传入请求。
使用 select(),不是每个请求都有一个进程,而是 通常只有一个进程“多路复用”所有请求,服务 尽可能多地请求每个请求。
所以使用 select() 的一个主要优点是您的服务器只会 需要一个进程来处理所有请求。因此,您的服务器 不需要共享内存或同步原语 不同的“任务”进行交流。
使用 select() 的一个主要缺点是您的服务器不能 表现得好像只有一个客户,就像使用 fork()'ing 解决方案一样。为了 例如,使用 fork()'ing 解决方案,在服务器 fork()s 之后, 子进程与客户端一起工作,就好像只有一个客户端 宇宙——孩子不用担心新的到来 连接或其他套接字的存在。使用 select(), 编程没有那么透明。
【讨论】: