【问题标题】:Using C sockets: Address already in use使用 C 套接字:地址已在使用中
【发布时间】:2013-05-09 01:51:59
【问题描述】:

所以我的程序的基本前提是我应该创建一个 tcp 会话,引导流量通过它,并检测任何连接丢失。如果连接确实中断,我需要关闭套接字并重新打开它们(使用相同的端口),以使连接看起来(几乎)从未中断。还应该注意的是,这两个程序将被视为代理(数据被发送给它们,如果连接中断,它会被存储,直到连接修复,然后数据被发送出去)。

我已经进行了一些研究并继续使用带有 SO_REUSEADDR 选项的 setsockopt() 来设置套接字选项,以便我可以重用地址。

这是我使用信号检测连接中断的基本算法:

  1. 初始设置套接字后,开始发送数据
  2. x 秒后,将标志设置为 false,这将阻止发送所有其他数据
  3. 发送一条数据让其他程序知道连接仍然打开,将计时器重置为 x 秒
  4. 如果我从程序接收到相同的数据,请将标志设置为 true 以继续发送
  5. 如果我在 x 秒后没有收到数据,请关闭套接字并尝试重新连接

(第 5 步是我得到错误的地方)。

本质上,一个程序是客户端(在一个 VM 上),一个程序是服务器(在另一个 VM 上),每个程序在每个 VM 上相互发送和接收数据,以及从另一个程序发送和接收数据。

我的问题是:既然我设置了socket选项后仍然出现这个错误,为什么检测到连接时不允许我重新绑定地址?

当检测到断开连接时,服务器是抱怨的(我关闭套接字,打开一个新的,设置选项,并尝试使用相同的信息绑定端口)。

另一件值得注意的事情是我从套接字接收数据的方式。如果我打开了一个套接字,我基本上是通过执行以下操作来阅读它:

while((x = recv(socket, buff, 1, 0)>=0){

    //add to buffer
    // send out to other program if connection is alive
}

由于我使用计时器来关闭/重新打开套接字,并且这是在不同的线程中,这会阻止套接字关闭吗?

【问题讨论】:

  • 我认为您可以查看这些答案以尝试解决您的问题:stackoverflow.com/questions/15788007/…
  • 那个循环条件应该是> 0,而不是>= 0。你在 EOS 上循环。
  • @TomásBadan 我之前确实看到了那个帖子,我尝试实现 setsockopt() 调用,但就像我说的,我仍然收到错误。
  • @EJP 谢谢,我忘了我没有改回来!
  • 你说服务器是那个抱怨的?为什么需要重新打开服务器上的套接字?当发生断开连接时,服务器不是只需要清理死套接字然后调用accept(listening_socket, ...),而客户端重新连接吗?

标签: c sockets


【解决方案1】:

SO_REUSEADDR 只允许有限重用端口。具体来说,它不允许重用某个其他套接字当前正在主动侦听传入连接的端口。

【讨论】:

    【解决方案2】:

    这里似乎有一种流行病,人们打电话给bind(),然后是setsockopt(),想知道为什么setsockopt() 不能修复bind() 上已经发生的错误。

    你必须先打电话给setsockopt()

    但我不明白你的问题。为什么你认为你需要使用相同的端口?你为什么要设置一个标志来阻止你发送数据?你不需要这些。只需处理send() 上的错误,如果它们出现,则在必要时创建一个新连接。不要试图超越 TCP。很多人都尝试过,但很少有人成功。

    【讨论】:

    • 对不起,我想我没有指定这个。我在实际绑定套接字之前调用 setsockopt() 。创建套接字时,该过程实际上是调用 socket(...),将返回传递给 setsockopt(...),然后使用 bind(...) 绑定套接字。重新连接是相同的过程,除了我先关闭套接字。使用相同的端口只是程序的规范之一,所以我无法解决这个问题。
    • 根据@ChrisDodd 的回答,您将不得不“绕过”它,因为这是不可能的。如果你关闭一个连接,它的本地端口最多会处于 TIME_WAIT 状态,两分钟内不能重用。整个事情从根本上来说是错误的,你可以告诉他们我们是这么说的。将规范发回它的来源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多