【问题标题】:Send and receive data by tcp socket in one thread在一个线程中通过 tcp socket 发送和接收数据
【发布时间】:2016-02-23 19:09:12
【问题描述】:

我有一个有 2 个线程的应用程序。第一个线程(主线程)和第二个线程(tcp-client-thread)。 main-thread 生成一些消息并将它们放入队列中以供tcp-client-thread 使用。 tcp-client-thread 必须将这些消息发送到服务器。但是,tcp-client-thread 也必须从服务器接收一些消息。

我该怎么做? recv 停止当前线程。为recv 设置超时?然后在recv 超时检查队列(来自main-thread)之后,如果有消息发送它们是否没有任何消息再次开始recv

【问题讨论】:

    标签: c++ sockets events pthreads


    【解决方案1】:

    您可以在一个非旋转/非延迟线程中执行 I/O,但它比另一个答案中建议的简单地创建另一个线程要复杂得多。简而言之,您必须修改代码以同时处理等待多种事件类型,例如,套接字上的事件或发送数据的条件信号。在 Windows 上,您将使用 WSAEventSelect + WaitForMultipleObjects 之类的东西来代替 select,而在 Linux 上,您将使用带有 select 的 eventfd 之类的东西。请注意,在处理套接字时,如果它被阻塞,您需要在发出 recv 之前检查可读性,并在发出 send 之前检查可写性,这样您就不会阻塞其中一个。就像我说的,创建一个发送线程更容易......

    【讨论】:

      【解决方案2】:

      您需要的是非阻塞/异步 I/O。 在尝试伪造任何代码之前,您应该阅读一些理论。 这篇文章,例如: http://www.wangafu.net/~nickm/libevent-book/01_intro.html

      【讨论】:

        【解决方案3】:

        如果您打算使用 2 个线程,您可能希望扩展到 3 个线程。让发送和接收函数在不同的线程上。

        send 线程正在休眠,直到主线程为其提供数据。具体来说,send 软件单元中的一个函数将数据放入队列,然后通知线程唤醒。线程唤醒并发送数据,直到队列为空,然后重新进入睡眠状态。

        相反,receive 线程会一直休眠,直到它接收到数据。它将数据附加到另一个队列,通知 main 线程接收到数据并返回睡眠。

        编辑 1:一个线程
        根据您的标题,如果您想在一个线程中执行 I/O,则需要有一个轮询循环(您可以有有限的等待,但不建议这样做)。

        Loop:  
          if (data received) then place data into input queue.
          if (data in input queue) process some data (use small chunks).
          if (data in output queue) send some data.
        end-loop.
        

        这个想法是保持小数据块以防止丢失传入的数据。在没有数据的情况下(并经过多次迭代),可以处理并输出数据。这将解决大多数同步问题。

        【讨论】:

          猜你喜欢
          • 2020-06-23
          • 2012-03-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-04
          • 2019-10-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多