【问题标题】:1 socket - send and recv in different threads1 个套接字 - 在不同的线程中发送和接收
【发布时间】:2014-07-17 15:04:46
【问题描述】:

我现在被困在设计/逻辑阶段。我有一个运行 2 个线程并使用 1 个连接到服务器的套接字的客户端。

在主线程中有 GUI 操作,当用户单击程序标题栏上的 X 时,程序将 CLOSE 数据包发送到服务器,服务器从用户列表中删除客户端 - 这没有问题。

当我添加允许运行服务器的人手动从服务器中删除用户的选项时出现问题。当管理员右键单击用户时,他可以踢他 -> 然后服务器向客户端发送 CLOSE 数据包,这可以工作,但这里有一个问题:

正如我所说,客户端在一个线程中使用 2 个线程,他发送 CLOSE 数据包,而在另一个线程中,他在不同的线程中等待它(阻塞)——该线程甚至在显示窗口之前就已启动。

所以我们这里是有问题的情况:

客户端加入服务器并想离开它 - 无法工作,因为客户端的第二个线程已经阻塞套接字并且第一个线程无法发送 CLOSE 数据包。

任何想法如何很好地解决它?

编辑:现在我不确定这是否有问题,因为有时它可以工作,有时第一个线程不发送数据或服务器不接收。

无论如何,我也刚刚读过recv并从不同线程的一个套接字上发送应该不是问题,所以我很困惑。

【问题讨论】:

  • 如果你使用 TCP 连接,则无需发送 CLOSE 数据包;您可以简单地关闭 TCP 连接的本地端,并且将通知另一端连接已关闭(无论如何您都需要处理这种情况,因为 TCP 连接可以“自发地”关闭,例如通过网络失败)。至于阻塞线程问题,我建议改用非阻塞 I/O,如果需要阻塞,在 select() 内部阻塞。这样,您的线程可以在必要时被唤醒(通过超时或通过在另一个套接字上发送数据)
  • 为什么如果第一个线程正在阅读,第二个线程不能发送 CLOSE?这样做的任何问题都是由于您自己的代码造成的。 API 中没有任何东西可以阻止它。
  • 好的,这正是我想听到的——现在我知道我必须在代码中找到它。

标签: windows multithreading sockets communication


【解决方案1】:

吸引被read()write()pselect 等阻塞的pthread 的注意力的一种方法是pthread_kill(),它将信号传递给特定的pthread。目标 pthread 必须设置为捕获您选择的“唤醒”信号(一个空的信号处理程序就可以)而不是屏蔽它。

但是,这里有个大问题……你无法判断pthread是否被阻塞,也无法判断它是否即将阻塞,所以信号可能会丢失!所以,下一个技巧是使用非阻塞 I/O 和pselect()——是的,这似乎违背了让 pthread 摆脱所有这些的目的!现在你要做的是在 pthread 中大部分时间屏蔽“唤醒”信号。但是,当 pthread 在pselect() 上“进入睡眠状态”时,您可以将 pselect 设置为在等待时取消屏蔽“唤醒”信号。这安排了可靠地传递信号。当 pselect 返回时,您必须检查错误,尤其是 EINTR

使用pselect(),您还可以设置一个虚拟管道,您也可以等待它。为了引起 pthread 的注意,您写入管道。我碰巧更喜欢信号方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    • 2017-10-25
    • 2014-11-25
    • 2017-07-05
    • 2016-08-31
    • 2012-10-05
    相关资源
    最近更新 更多