【问题标题】:accept a connection inside a pthread接受 pthread 内的连接
【发布时间】:2013-06-06 13:06:31
【问题描述】:

我希望有人可以帮助我解决我的问题。 我尝试使用 C 制作客户端/服务器 FTP 应用程序,

我的程序实现是这样的:

main()
{
1)create socket
2)bind on port 8888
3)listen
5) while(accept)
  { 
    5) create  pthread1 to handle the connection using function1
    6)join the pthread1
  }
}

function 1()
{
1)take the file descriptor from the main
2) discusses with client using the descriptor (send/recv)
3) create pthread2 to handle data exchange
4) join the pthread 2
5)free the descriptor
}
function 2()
{
1)create socket
2)bind on port 8889
3)listen
4)accept
}

我的问题: -当我尝试第一个客户端时,一切正常,两个连接都做得很好! -当我尝试第二个客户端时,第一个连接正常,但第二个出现 BIND 错误! -我真的不知道有什么问题。 -谢谢你的帮助。

【问题讨论】:

    标签: linux sockets pthreads


    【解决方案1】:

    (1) 在我看来,您一次只能运行一个客户端线程 (pthread1)。在main() 中,您将阻塞pthread_join,直到第一个线程完成。因此,如果您继续沿着这条路走下去,您要么必须将这些线程创建为分离的,要么使用另一种方法来加入 thread1。或者,更好的是,使用线程池。

    (2) 我的猜测是您的第二个 bind 失败了,因为它在第一次连接后已经在使用中。即使第一个连接在建立第二个连接之前将其关闭,在它再次可用之前也存在时间延迟。你可以绕过这个滞后,但这不是处理这个问题的方法。

    而是让第二个bind 选择自己的侦听端口。为此,您在传递给bind 的地址结构中指定端口0。然后系统将为您选择一个侦听端口,而不是所有被硬编码以在 8889 上运行的端口。显然,您必须告诉客户端(通过在 pthread1 中建立的控制连接)“嘿,在此端口上连接到我以传输数据”反过来,客户端必须建立连接。根据上面的大纲,您需要进行一些设计更改才能实现这一点。

    另一种方法显然是只保留硬编码的 8889 侦听端口,但只绑定一次。这有一些问题,但如果这只是一个练习,显然很容易实现。

    警告:我已经很久没有想到 FTP 服务器了,但这是被动模式的基本概述。

    【讨论】:

    • 非常感谢您的回答,我会试试这个并告诉您结果。
    • 现在我编辑了我的代码:我做了一个从 1025 到 40000 的 for 循环,然后在确定绑定完成后我将端口号发送给客户端,现在所有客户端都可以连接为我想要,非常感谢。
    • @badr assa - 这是丑陋的一面且效率低下,但如果您处理 bind 错误并跳过已在使用的端口,它将起作用。如果遇到问题,建议您切换到我上面建议的方法。将 bind 传递给 0 端口,然后使用 getsockname 检索它分配给您的端口。它更干净。无论如何,我很高兴你在路上。编码愉快。
    【解决方案2】:

    thread-2使用的数据交换端口应该是thread-1与客户端进行会话确认时预先选择的随机端口。


    此外,您最好还是分离运行线程,因此无需加入它们,因为在当前设计中,加入至少会阻塞主服务器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 2012-08-25
      • 2012-01-16
      • 1970-01-01
      • 2021-05-15
      • 1970-01-01
      相关资源
      最近更新 更多