【问题标题】:TCP server sending and receiving data multiple clients with multithreadingTCP服务器通过多线程发送和接收多个客户端的数据
【发布时间】:2013-02-25 17:35:29
【问题描述】:

我想设计一个监听 x 个客户端的 TCP 服务器。 X 很小,比如大约 10 并且它是固定的。客户可以随时连接。建立连接后(accept() 成功)我为每个客户端生成一个线程并处理它们。

在这个handle() 函数中,我想向客户端发送命令并相应地接收数据。

问题: 一旦从服务器发送命令,客户端就会通过连续发送数据来响应。如何将命令发送回客户端以停止它?与当前代码一样,我正在循环接收来自客户端的数据。

  1. 我不知道如何在接收过程中从服务器线程发送命令,比如在建立连接后我是否需要另一个线程(发送 cmds)?
  2. 如何连续接收客户端数据,同时发送命令?根据用户输入向每个客户端发送命令。 (假设用户希望 client1 开始发送数据,那么我必须向 client1 发送 START。并且用户希望停止 client1 发送,所以我需要向 client1 发送 STOP 如果用户希望将 data3 cmd 发送到客户端 4 然后向client4发送命令DATA3等,这种情况下如何识别客户端?基本形成一个小协议**

下面的代码在我可以监听套接字和客户端连接并发送数据的地方工作。我不确定如何将用户输入的命令发送到正确的客户端(比如 client4)并同时接收。

【问题讨论】:

  • 您能否更深入地了解您尝试创建的应用程序。从您的帖子来看,您想要实现的目标并不明显。
  • @pradheep,我想根据我的命令将数据从我的几个设备传输到服务器。由于我的设备不断生成数据,我需要与他们交流说 START SENDING、END、GETTHISDATA,有时我还需要连续获取数周的数据,有些需要 5 分钟等。

标签: c multithreading sockets network-programming


【解决方案1】:

如果您想要真正连续流式传输数据并并行想要交换命令,您将无法绕过额外的连接来建立命令通道。替代方案将是某种多路复用。流式传输数据块,检查命令,流式传输下一个数据块,再次检查命令... - 复杂且容易出错,因为流不断中断...

stone old ftp 协议做了类似的事情:http://en.wikipedia.org/wiki/Ftphttps://www.rfc-editor.org/rfc/rfc959(参见第 2.3 章中的 ascii 艺术)

【讨论】:

  • 谢谢。但是FTP一旦开始向服务器发送数据就不会等待任何命令。
  • 对不起,我没看。它相当大的文件。会做。谢谢
  • 我所说的相似之处在于ftp除了一个或多个数据流之外还设置了一个单独的conteol通道。 @M4n07
【解决方案2】:

假设您想让另一个线程发起发送命令的请求,您可以使用标准异步 i/o 完成您想要的操作,添加另一个通道 - 管道 - 以接​​收来自另一个线程的命令。伪代码:

Master thread:
while(1) {
    newsocket = accept(listen socket)
    pipefds = pipe()
    new thread(Receiver, newsocket, pipefds.read)
}

Receiver thread:
while(1) {
    readfds = [ pipefds.read, newsocket ]
    poll( readfds )  // wait for there to be data on one of the fds
    if (data ready on newsocket) {
           read (newsocket)
           process data
    }
    if (data ready on pipefds.read) {
           read (pipefds.read)
           send command
    }
}

Commander thread:
write (pipefds.write, command)

只要套接字上有数据要读取,或者另一个线程发送了需要发送到远程连接的命令,主接收器循环中的select就会唤醒。

查找信息的关键系统调用是poll(或select)和pipe

【讨论】:

    【解决方案3】:

    呜呼!我的朋友,你决定深入研究一个漂亮毛茸茸的主题。

    首先让我重新表述您的问题:您的程序一次只能等待一件事。如果它正在等待receive,它就不能等待send。所以你不能同时发送和接收。

    这通过多路复用解决:等待多个事物。

    1. 谷歌搜索关键字:iomultiplexingselectpoll
    2. SO 相关问题:read and write to same socket (TCP) using select

    另一种方法是进入nonblocking-read -> nonblocking-write -> sleep 循环。这显然不是最佳的,但对于您的情况可能就足够了。

    【讨论】:

    • 谢谢。但是我必须以毫秒为间隔从每个客户端接收数据。这就是为什么我不愿意使用睡眠方法。有没有可用的伪代码。
    【解决方案4】:

    过去,我为无法同时通信的低级设备设计了自己的双向协议,这让我很开心。您可以使用的一种方法是相互让步:建立一种在客户端和服务器之间传递消息的机制。流式传输您需要发送的任何命令或消息,然后将流传输到另一端。然后另一方将流式传输任何消息或命令,然后将流传递给原始侧。这种机制的唯一问题是它对于高 ping 连接(例如国际互联网连接)非常滞后。

    这已经提到过,但我不妨重新讨论一下。计算机已经在其网络硬件中内置了多路复用,因此您可以进行“并发”发送/接收调用。只需为每个连接运行一对线程:一个接收线程和一个发送线程。这应该是最稳健的解决方案。

    【讨论】:

      猜你喜欢
      • 2021-12-04
      • 2016-09-26
      • 1970-01-01
      • 2014-03-08
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-03
      相关资源
      最近更新 更多