【发布时间】:2013-03-02 19:30:59
【问题描述】:
我用纯 C 语言编写了这个小型服务器应用程序,它监听给定端口中的传入连接,非常简单。
它使用通常的套接字初始化过程,创建socket() 然后bind() 到端口,说它是listen(),并无限循环通过select() 等待传入连接到accept()。
一切都很好,就像一个魅力,除了如果我让这个东西运行几个月,监听端口会关闭,而应用程序服务器会继续运行而不知道它,因为我写它是为了相信监听套接字会如果没有被告知,则不会关闭。
所以问题是:为什么在我的应用程序不关心的情况下关闭端口,我可以做些什么来防止它发生?
这是预期的行为吗?我应该检查某种异常还是在侦听套接字上进行“健康检查”以在必要时重新打开它?
代码:https://gist.github.com/Havenard/e930be035a3bee75c018(是的,我意识到我使用0 作为错误提示,这是不好的做法和东西,但正如我在 cmets 中解释的那样,当我设置套接字时,它与问题无关文件描述符到0是停止循环并关闭应用程序。
【问题讨论】:
-
不正常。我会怀疑您的应用程序中存在某种资源泄漏,例如文件描述符用完,因为您没有关闭 accept() 返回的新套接字。
-
Select() 将导致报告/错误的文件描述符无效。也许你通过 dup2() 关闭它?
-
这不正常。显示您的代码。
-
源代码上的一些(风格)提示:1)main() 函数太大而无法阅读 2) 信号处理程序在 main() 中定义。 C 没有嵌套函数。 3)你测试你的文件描述符为零(
'if (skt_accept == 0)... )尝试使用-1作为无效的文件描述符(并在无效时将它们设置为-1)4)在你的gobackground()函数中你在关闭filedesctiptors 0,1后执行printf, 2. 5) 你真的应该忽略 select() 的一些 -1 返回,比如 EAGAIN。 6)链表是凌乱和过于复杂,恕我直言。 7)' '比 0x20 更具可读性 -
@Havenard 是的,我不是 taklink 关于在侦听套接字上发送,而是在接受的套接字上发送。您的 30 个客户端中的一个可能会在您仍在与您的 irc/like 服务器通话时突然断开与它的连接。当它发生时,如果您尝试向客户端套接字发送()某些东西,整个程序将使用 SIGPIPE 退出。