【问题标题】: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 之前检查可写性,这样您就不会阻塞其中一个。就像我说的,创建一个发送线程更容易......
【解决方案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.
这个想法是保持小数据块以防止丢失传入的数据。在没有数据的情况下(并经过多次迭代),可以处理并输出数据。这将解决大多数同步问题。