我编写了简单的转发代理服务器,它接受来自客户端的端口范围内的连接并转发它们。
建立连接后,我将它们添加到我使用 select() 监视的套接字列表中。我知道更好的方法是使用 read() 每个 fd 一个线程。
我有一些限制,因为我不能每个连接使用一个线程,所以我使用 select()。但是后来我不知道客户端是否关闭了连接,因为 select 没有告诉我。有什么办法可以弄清楚吗?
我编写了简单的转发代理服务器,它接受来自客户端的端口范围内的连接并转发它们。
建立连接后,我将它们添加到我使用 select() 监视的套接字列表中。我知道更好的方法是使用 read() 每个 fd 一个线程。
我有一些限制,因为我不能每个连接使用一个线程,所以我使用 select()。但是后来我不知道客户端是否关闭了连接,因为 select 没有告诉我。有什么办法可以弄清楚吗?
当 select() 告诉您在已放入读取集中的文件描述符上有一个事件时,您必须通过调用 read() 或 recv() 来读取数据。
如果 read() 返回 0,则另一端已关闭其连接端。如果 read() 返回 -1,则发生了一些错误,您必须检查 errno 以查看它是什么。如果 errno 是 EAGAIN 或 EWOULDBLOCK,您应该简单地返回到您的 select() 循环,否则您应该关闭套接字。
当连接关闭时,选择返回套接字的读取事件。关闭后从套接字读取数据时,重新调整值为 0。
使用 select 比使用每个连接的线程更好。您可以在延迟(每个线程更多连接)和资源使用(每个线程更少连接)之间选择自己的策略。
select() 的第四个参数采用文件描述符的位掩码来监视异常。在那里设置位,就像您为读取和/或写入所做的那样,并在选择返回后测试它们。如果设置了它们,您可以通过正常调用 read() 来检索错误。