【问题标题】:Cannot receive UDP Stream from Port 2368 (Linux) C无法从端口 2368 (Linux) C 接收 UDP 流
【发布时间】:2012-02-13 04:22:28
【问题描述】:

我目前正在使用在端口 2368 上提供 UDP 数据流的激光传感器。我可以使用 Wireshark 查看数据包。

由于我无法发布图片,因此我编写了 Wireshark 为数据包显示的内容:

来源:192.168.17.141 目的地:192.168.3.255 协议:UDP 源端口:https (443) 目标端口:opentable (2368)

但是,我想通过以下示例 C 程序使用套接字读取数据包:

int main(int argc, char *argv[])
{
   int sock, n, res;
   unsigned int length = 1206;
   char* buffer = new char[1206];  

   sock= socket(AF_INET, SOCK_DGRAM, 0);
   if (sock < 0) error("socket");

   uint16_t udp_port = 2368;
   sockaddr_in my_addr;                    
   socklen_t len = sizeof(sockaddr_in);
   memset(&my_addr, 0, sizeof(my_addr));   
   my_addr.sin_family = AF_INET;           
   my_addr.sin_port = htons(udp_port);    
   my_addr.sin_addr.s_addr = INADDR_ANY;

   cout << my_addr.sin_family << endl;
   cout << my_addr.sin_port << endl;
   cout << my_addr.sin_addr.s_addr << endl;


   res = bind(sock, (sockaddr *)&my_addr, sizeof(sockaddr_in));
   if (res == -1)
     {
       perror("bind");                 
       return -1;
     }


   while (true)
   {
       n = recvfrom(sock,buffer,1,0,NULL,NULL);
       if (n < 0) error("recvfrom");
   }

   close(sock);
   return 0;
}

程序成功直到到达recvfrom()。套接字在那里等待包裹并且没有收到任何东西。我用 Winsock 为 Windows 编写了相同的程序,它运行良好。由于我对 Linux 操作系统比较陌生,所以我不知道如何解决这个问题,非常感谢您的建议!

附加信息:我手动为eth4分配了以下IP和网络掩码(这是设备连接的接口):

IP:192.168.3.5 海里:255.255.255.0

【问题讨论】:

  • 您的程序是 C++,而不是 C,因为您使用 cout 变量,它是 C++ 类 iostream 的一部分。
  • 192.168.3.255 将是一个网络掩码为 255.255.255.0 的广播地址,您通常必须启用 SO_BROADCAST 套接字选项才能接收这些数据包。但是如果 192.168.17.141 发送到你的机器,它不能发送到你的 /24 网络的广播地址,所以这里的网络掩码肯定有一些混淆。
  • 您期待 1 字节大小的数据包?

标签: c++ linux sockets udp


【解决方案1】:

设置 SO_BROADCAST 选项,即使是接收。根据 socket(7) 手册页:

SO_BROADCAST:
设置或获取广播标志。启用后,数据报套接字接收发送到广播地址的数据包,并允许它们将数据包发送到广播地址。此选项对面向流的套接字没有影响。

也可能是您的界面配置不正确。验证您是否为相关接口配置了 192.168.3.xxx/24 地址。

【讨论】:

    【解决方案2】:
    char buffer[1200+6]; /* no need for dynamic buffers */
    ...
    n = recvfrom(sock, buffer, sizeof buffer, 0, NULL, NULL);
    

    顺便说一句,您对 recvfrom() 的使用相当于

    n = recv(sock, buffer, sizeof buffer, 0);
    

    ,甚至:

    n = read(sock, buffer, sizeof buffer);
    

    【讨论】:

      【解决方案3】:

      你有

      IP: 192.168.3.5 NM: 255.255.255.0
      

      Source: 192.168.17.141 Destination: 192.168.3.255
      

      如果不涉及路由器,这将无法工作。试试

      IP: 192.168.3.5 NM: 255.255.0.0
      

      作为临时措施,但一定要阅读 IP

      编辑:也许更好地查看您的激光传感器并将其设置为192.168.3.[something free],将目标直接设置为您的192.168.3.5,并稍后调试广播。

      【讨论】:

      • 感谢您的回复!不幸的是,无法更改传感器的 IP!我也尝试了您建议的配置,但没有成功。
      • 如果无法更改传感器的 IP,您可以将目标和 Linux 主机的 IP 更改为 192.168.17.x 范围内。如果这不可能,您还需要一个启用广播的路由器。您在 Windows 上使用了哪些 IP 设置?
      • 我对我的 Windows 应用程序使用了与上述相同的设置(192.168.3.5、255.255.255.0),它运行良好。我只是将我的 IP 设置为 192.168.17.5,但我仍然没有收到任何包裹。是不是有什么东西阻塞了 2368 端口?
      • @user1156079 您应该将 linux PC 上的网络掩码更改为 255.255.0.0 ,而不是 IP。如果这仍然不行,您应该尝试在套接字上设置套接字选项 SO_BROADCAST (int bcast = 1; if(setsockopt(your_socket, SOL_SOCKET, SO_BROADCAST, &amp;bcast, sizeof bcast) == -1) {perro("setsockopt");})
      猜你喜欢
      • 2017-12-24
      • 2020-03-05
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 2018-05-08
      相关资源
      最近更新 更多