【问题标题】:UDP - Multi-server single clientUDP - 多服务器单客户端
【发布时间】:2018-01-16 15:56:02
【问题描述】:

我有一台带有 C 代码的 linux 计算机,它必须通过 UDP 与 4 个不同的设备进行通信。计算机向每个设备发送不同的命令并接收响应,有时是并行的......

我是一个完美的初学者,并设法使用 UDP 套接字与一台设备进行通信。但是现在,我正在寻找一种与所有这些设备进行通信的方法,我想称之为“多插座”,但我不知道在哪里看/搜索什么词来找到一种方式......

我的 linux 电脑是客户端和所有设备服务器。我的电脑只有一个 eth 端口,必须使用交换机才能访问所有设备。我想创建如下功能:

sendcmd(IPnumber, PORTnumber, cmd , ...)
readbuff(IPnumber, PORTnumber, buff, ...)

所以我可以选择哪个 IP 将接收 cmd ...我不知道这是否可能或者我是否需要打开套接字,然后关闭并使用另一个 IP 重做操作...

那么,如果我设法让自己被理解,我应该在哪里寻找解决问题的方法?

谢谢!

【问题讨论】:

  • 处理多个连接的方法有很多。您可以使用多个进程,每个进程有一个“连接”。或线程而不是进程。或使用四个(在您的情况下)套接字将数据发送到每个套接字,然后使用例如select 或类似的轮询函数来检查正在接收的数据以及来自哪个套接字。
  • 如果您向所有节点发送完全相同的数据,您可以查看多播。
  • 使用 UDP,sendto/recvfrom 就是您要找的。单个套接字可以与任意数量的端点通信。
  • @user58697 当我使用时:sendto(socket_fd , cmd_final, BUFFLEN , 0 , (struct sockaddr *)&serv_addr, serv_len) 定义我的 IP 和端口的唯一部分是 serv_addr,因为我之前使用:serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); serv_addr.sin_addr.s_addr = inet_addr("INADDR_ANY") 和:inet_pton(AF_INET, SERVER, &serv_addr.sin_addr); 定义它所以我需要创建多个struct sockaddr_in serv_addr 以选择如下IP/PORT? sendto( ... (struct sockaddr *)&serv_addr_**i** ...) 是吗?谢谢!

标签: c linux sockets udp


【解决方案1】:

您可以在场景中使用单个 UDP 套接字。您可以在应用程序的整个生命周期内保持套接字打开。

UDP 不是面向连接的。 UDP 套接字也不分为客户端套接字和服务器套接字。 UDP 套接字总是绑定到本地端口,或者隐式(通常用于纯客户端)或显式(通常用于服务器)。在您的情况下,您并不关心您的 UDP 客户端的端口。

要发送到您的四个 UDP 服务器,您可以使用sendto()。这使您可以指定 UDP 数据包发送到的目标 IP 地址和端口。

要从您的四个 UDP 服务器接收,您可以使用recvfrom()。这将告诉 UDP 数据包来自的 IP 地址和端口。

您很可能希望有某种接收循环。如果你想在你的应用程序中做任何其他事情,你很可能想让recvfrom() 非阻塞,或者你想让接收循环在它自己的线程中。但这超出了您的问题范围。

UDP 最重要的方面是它不是一种协议(尽管它的名称具有误导性)。它是协议的一块拼图。它是开发您自己的协议的工具。但我假设您手头已经有一个由外围设备定义的特定协议。

【讨论】:

  • 当我使用时:sendto(socket_fd , cmd_final, BUFFLEN , 0 , (struct sockaddr *)&serv_addr, serv_len) 定义我的 IP 和端口的唯一部分是 serv_addr,因为我之前用:serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); serv_addr.sin_addr.s_addr = inet_addr("INADDR_ANY") 和:inet_pton(AF_INET, SERVER, &serv_addr.sin_addr); 定义了它,所以我需要创建多个struct sockaddr_in serv_addr 选择如下 IP/PORT 吗? sendto( ... (struct sockaddr *)&serv_addr_**i** ...) 对吗?谢谢!
  • 是的。或者,您可以在方便时重新使用相同的 serv_addr 并每次修改要发送到的 IP。本质上,您可以为每次调用 sendto() 指定目标地址,这使您能够通过同一个套接字发送到任意数量的设备。
  • 感谢您提供详细信息。您能否给我看一个指定目标地址的 sendto() 示例代码,我不确定我是否理解正确。我会说该方法只是更改SERVER(=IP) 并重做inet_pton(AF_INET, SERVER, &serv_addr.sin_addrso sendto() 已考虑到新的服务器IP,但我真的不确定...谢谢您的帮助,真的很有帮助!
  • 是的,完全正确。您的sentto() 调用会将数据包发送到您的&serv_addr.sin_addr 指向的任何位置,其中包含IP 地址和端口。这是数据包将要到达的目标地址。如果需要,您可以将每个数据包发送到不同的 IP 和/或端口。没有UDP连接之类的东西。从最后一次调用 sendto() 到下一次没有持久状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-22
  • 2012-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多