1

我猜我需要做线程,但在我教自己一些不好的做法之前,我想确保我以正确的方式去做。

基本上我有一个“聊天”应用程序,可以告诉它监听或 ping 收件人的 ip 地址:端口(在我目前的情况下只是 127.0.0.1:1300)。当我打开我的应用程序两次(第一个监听,第二个发送 ping)时,我选择一个并告诉它监听(这是一个 While 语句,它一直在监听直到它收到一个 ping 消息)和另一个会ping通它。它很有效

问题是当我单击“侦听 ping”按钮时,它将进入胶合“向下”模式并“视觉”冻结,但是它将 UDP 数据包消息打印到控制台,所以我知道它实际上并没有被冻结。所以我的问题是如何制作它,以便我可以单击“收听”按钮并让它“收听”,同时有一个“工作”取消按钮,以便用户可以取消该过程,如果它花费的时间太长?

4

1 回答 1

2

这很可能是因为您使用了同步(阻塞)套接字 IO。您的服务器应用程序很可能会阻塞recv()/ read(),这会阻塞线程的执行,直到某些数据到达;然后它处理数据并返回阻塞状态。因此,您的按钮在按下时由 GTK 呈现。

基本上,有两种通用的方法来解决这个问题。第一个是线程。但我建议在更简单的应用程序中反对它;这种方法通常容易出错,并且很难正确实施。

第二种方法是异步 IO。首先,您可以使用select()/poll()函数等待多个 FD 之一发出信号(在诸如“收到数据”、“发送数据”、“接受连接”之类的事件上)。但是在主循环不能立即使用的 GUI 应用程序中(我不确定 GTK,但在许多 GUI 工具包中都是这种情况),这通常是不可能的。在这种情况下,您可以使用通用异步 IO 库(如boost asio)。使用 GLIB、IIRC,您可以为套接字交互创建通道 ( g_io_channel_unix_new()),然后为它们分配回调 ( g_io_add_watch()),当有趣的事情发生时将调用它们。

异步 IO 背后的想法非常简单:您要求操作系统做某事(发送数据、等待事件),然后您做其他重要的事情(GUI 交互等),直到您请求的事情完成(您必须能够接收此类事件的通知)。

因此,这就是您接下来可能要学习的内容:

  • select()/ poll()(后者一般比较好用)
  • 提升 asio 库
  • GLIB 通道和异步 IO
于 2012-12-17T03:34:29.227 回答