【问题标题】:How to detect socket is closed in forward proxy如何检测套接字在转发代理中关闭
【发布时间】:2012-08-08 20:39:36
【问题描述】:

我编写了简单的转发代理服务器,它接受来自客户端的端口范围内的连接并转发它们。

连接建立后,我将它们添加到我使用 select() 监视的套接字列表中。我知道更好的方法是使用 read() 每个 fd 一个线程。

我有一些限制,因为我不能每个连接使用一个线程,所以我使用 select()。但是后来我不知道客户端是否关闭了连接,因为 select 没有告诉我。有什么办法可以弄清楚吗?

【问题讨论】:

  • 我想我找到了答案。我将exceptfd 值作为NULL 传递。 :( 我想如果我使用与 readfds 中传递的相同文件描述符集传递 exceptfd ,那么我应该会很好。我会尝试一下。如果还有更多内容,请告诉我。

标签: c linux networking tcp network-programming


【解决方案1】:

当 select() 告诉您放置在读取集中的文件描述符上有一个事件时,您必须通过调用例如读取数据。 read() 或 recv()。

如果 read() 返回 0,则另一端已经关闭了它的连接端。 如果 read() 返回 -1,则发生了一些错误,您必须检查 errno 以查看它是什么。如果 errno 是 EAGAIN 或 EWOULDBLOCK,您应该简单地返回到您的 select() 循环,否则您应该关闭套接字。

【讨论】:

  • 嘿,exceptfd 有什么用还是这样就够了?
  • 一般来说没什么用,我会远离它。见stackoverflow.com/questions/1342712/…
  • 还有一个问题:万一客户端崩溃,有没有使用exceptfds?
  • 不,至少没有任何有用的用途。
  • 那么,客户端崩溃时如何关闭socket?
【解决方案2】:

当连接关闭时,选择返回套接字的读取事件。关闭后从套接字读取数据时,重新调整值为0。

使用 select 比使用每个连接的线程更好。您可以在延迟(每个线程更多连接)和资源使用(每个线程更少连接)之间选择自己的策略。

【讨论】:

    【解决方案3】:

    select() 的第四个参数采用文件描述符的位掩码来监视异常。就像您为读取和/或写入所做的那样设置这些位,并在选择返回后测试它们。如果已设置,则可以正常调用 read() 检索错误。

    【讨论】:

    • 当连接关闭时,您会收到 0 字节读取事件(eof 但不是错误)
    • 对,对不起。我应该说清楚的。显然,如果系统调用返回一个错误,你确实会得到一个错误。
    • 例如,如果收到绑定到套接字的数据包的 ICMP 错误,您将收到错误。但是,如果连接正常关闭(在远程端关闭或关闭)并且通过套接字接收到 FIN 数据包,那么您将获得读取事件并从指示 EOF 的套接字读取 0 个字节。
    • 已建立的 TCP 连接中的数据没有超时。维护连接超时是您自己的任务。
    • 是的,一旦我们从对方收到一个 FIN,select 报告套接字准备好读取,当我们发出读取时,它将返回 0。
    猜你喜欢
    • 2014-10-21
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 2022-11-09
    • 2015-08-22
    相关资源
    最近更新 更多