c - 从 Linux C 向许多 Android 手机发送 UDP 消息

标签 c linux sockets udp intel-edison

重写以尝试弄清楚我需要什么。

我的目标是在运行 C 和 Linux 的嵌入式英特尔爱迪生处理器中复制 Digital Yacht 制造的设备的功能。该设备通过 UDP 发送到 iRegatta 等手机应用程序。要设置应用程序,只需输入端口号。在应用程序的 UDP 模式下没有输入 ip 地址。我认为这是微不足道的,但到目前为止这里的专家都说这是不可能的,所以它一定不是微不足道的。也许这就是为什么在我所有的阅读时间中我找不到一个例子。我被否决是因为,有人告诉我,我试图做的事情是不可能的,但事实并非如此。我不知道它是怎么做到的,这就是我来这里找专家的原因。

我想发送可能如下所示的 nmea 消息:

$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

并且我希望任意数量的随机 Android 手机能够通过适当的应用程序接收它们。有许多应用程序可以设置为接收 UDP 数据,您只需指定一个端口号即可。应用程序的设置不涉及 IP 地址。此外,我不希望从 Android 手机收到任何信息。这是一种方式,无法重新传输,因此如果消息没有到达那里,下次还有机会。所有内容每秒更新一次。

我尝试了以下方法,但我没有在应用程序中获取数据。从评论来看,我一定需要在我的 Linux 机器中添加某种路由器功能。

void init_udp(){
    return;
    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock < 0){
        printf("ER UDP Socket error\n");
    }
    else printf("UP Socket %d OK\n",sock);
}

void write_udp(char *buf){
    return;
// nmea data is in buff
    if (sock >= 0){
        int on = 1;
        setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on) );
        struct sockaddr_in    address = {0};
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = inet_addr( "255.255.255.255" ); //
        address.sin_port = htons( 3000 );
        if ( sendto( sock, buf, strlen(buf), 0, (struct sockaddr*)&address, sizeof(address) ) < 0) printf("ER UDP send error\n");
        else {
            printf("UP %s\n",buf);
        }
    }
}

我不太确定我需要做什么。

最佳答案

您要做的是将 UDP 数据包发送到广播 IP 地址。这将发送到子网中的东西。 例如 10.255.255.255 是 10.x.x.x 子网的广播地址。您还可以使用全局 255.255.255.255,它也应该发送到您的子网,现在没有路由器会将其传递给另一个路由器。

您还需要让您的套接字能够发送广播消息。特别是您需要设置选项 SO_BROADCAST。由于 BOOL,以下是专门针对 Windows 的。对于大多数平台,它大概是一个 int。

BOOL on = TRUE;
setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on) );

此外,您不能对 UDP 套接字使用 send(),除非它“已连接”,因此您应该使用 sendto() 并使用广播地址。

要指定一个地址和端口,使用需要创建一个socket地址。

struct sockaddr_in    address = {0};

address.sin_family = AF_INET;
address.sin_add.s_addr = inet_addr( "255.255.255.255" );
address.sin_port = htons( 3000 );

sendto( sock, buff, strlen(buff), 0, (struct sockaddr*)&address, sizeof(address) );

注意类型转换的使用。这是因为 sendto 需要一个 sockaddr ,它是一个通用的地址类型,这里我们专门使用一个 IPV4 地址。 sockaddr_in 映射到 sockaddr

关于c - 从 Linux C 向许多 Android 手机发送 UDP 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33006987/

相关文章:

node.js - 如何使用 NodeJS 从客户端获取套接字的 header 请求

c - c 中的编码和解码文本

c - 嵌套结构和指针

c++ - 在 C 程序中使用 C++ 库

linux - 如何检查 X 服务器是否正在运行?

linux - 混合 WxWidgets 和 GTK+

php - UTF-8贯穿始终

c - 从结构数组中输出随机元素

javascript - NodeJS 套接字有时工作

c - 在 C 中使用 socket_stream 传输 jpg 文件