【问题标题】:Handle postthreadmessage() inside a thread which is blocking in while(1) loop or use "Event Driven Sockets"在 while(1) 循环中阻塞的线程内处理 postthreadmessage() 或使用“事件驱动的套接字”
【发布时间】:2013-05-14 10:55:11
【问题描述】:

我有一个单服务器多客户端 udp 应用程序。有一个带有单个套接字 (socket#1) 的单个线程 (thread#1) 可以连续地从 client#1 接收数据。这个接收线程的任务是在它的套接字上不断地接收数据。

我在服务器应用程序 GUI 上有一个按钮,上面写着“向 Client#1 发送数据”。当按下这个按钮时,我希望我的接收线程暂停接收并在 socket#1 上发送一些数据,当数据发送时,继续接收。

如何做到这一点?如果我什至在按下按钮时 postthreadmessage() ,接收线程不会检查这些发布的消息,因为它总是在 while 循环中接收消息。它如何检查与按下的按钮对应的已发布消息?

编辑:另一个建议

如果我将套接字设置为“事件驱动”会怎样?即,每当套接字上有一些数据可供读取时,就会生成 FD_READ 事件并且我可以在套接字上读取,并且每当我想在套接字上写入一些数据时,我都会生成一个事件 FD_WanttoWrite,然后将数据写入套接字上。类似的事情可能吗?

(我知道 FD_READ,但是当我想在 Socket 上写东西时我不确定 FD_WanttoWrite)

【问题讨论】:

    标签: c windows sockets winapi network-programming


    【解决方案1】:

    您真的不需要暂停阅读线程。只需 send/to() 立即从按钮 Click 处理程序内部使用相同的套接字(甚至是不同的套接字,因为 UDP 是无连接的)的数据。

    暂停阅读线程的唯一真正原因是,如果发送的数据收到您不希望接收线程看到的响应。如果是这种情况,那么您有几个选择:

    1. 让接收线程将任何响应传递给按钮单击处理程序,以便在需要时进行处理。

    2. 向接收线程添加一个标志,告诉它停止从套接字读取。让按钮在发送时设置标志,然后在完成时清除标志。让接收线程的循环使用 select() 并设置一个小的超时,这样循环的每次迭代都可以检查标志并在标志设置时跳过读取。

    3. 按照您的建议,切换到事件驱动的套接字并在接收线程中使用消息循环。然后你可以将消息传递给线程,例如当 FD_READ 消息到达时告诉它跳过阅读的消息,以及恢复阅读的另一条消息。如果您希望线程代表按钮调用send/to(),您也可以为此发送消息,并且在发送过程中任何读取都将被隐式阻止。

    【讨论】:

    • 感谢您的所有建议。首先,我希望我的接收线程在发送时暂停,因为发送和接收线程都将使用一个套接字,所以为了避免任何同步问题,我只希望一个线程在一个时间。
    • 我想选择您提供的选择#3,但我不确定如何在我想要的时候生成事件
    • 套接字是双向和线程安全的。一个线程可以从一个套接字读取,而另一个线程同时写入同一个套接字,而无需同步它们。
    • 是的,你这样做了,因为你自己说过 - PostThreadMessage()
    【解决方案2】:

    您可以从另一个线程执行此操作(即:Gui 或不同于您的接收线程的新后台线程)。您需要访问套接字,因此您可能需要调整其范围。

    【讨论】:

    • 所以你的意思是我必须有一个单独的线程用于发送(),并且用于发送的套接字必须与用于接收的套接字相同?
    • 看看我在我的问题中添加的另一个建议。这可能吗?
    • 就像 Remy 所说...UDP 套接字是无连接的...您所需要的只是您的客户端正在侦听的 IP 地址和端口号,您可以创建一个新的套接字并使用该套接字发送。 .但是需要注意的是,如果客户端回复并使用 recvfrom 调用中的地址,它将转到服务器的新套接字,而不是您在服务器中使用的套接字接收循环。
    • 如果您在发送时没有理由在接收循环中“停止阅读”(我很难想象您为什么会这样做),那么我不明白您为什么需要事件驱动方法
    猜你喜欢
    • 2017-01-28
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 2016-04-21
    相关资源
    最近更新 更多