在一个线程中通过 tcp 套接字发送和接收数据

Send and receive data by tcp socket in one thread

本文关键字:套接字 tcp 数据 一个 线程      更新时间:2023-10-16

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

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

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

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

如果要使用 2 个线程,则可能需要扩展到 3 个线程。 让发送和接收函数位于不同的线程上。

发送线程处于休眠状态,直到主线程为其提供数据。 具体来说,send软件单元中的函数将数据放入队列,然后向线程发出唤醒信号。 线程唤醒并发送数据,直到队列为空,然后返回睡眠状态。

相反,接收线程在接收数据之前处于休眠状态。 它将数据追加到另一个队列,通知线程已收到数据并返回睡眠状态。

编辑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.

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