0

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

我的目标是在运行 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);
        }
    }
}

我不确定我需要做什么。

4

1 回答 1

2

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

您还需要使您的套接字能够发送广播消息。特别是您需要选项SO_BROADCAST集。以下是专门针对 Windows 的,因为BOOL. 它可能是大多数平台的 int 。

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

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

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

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

于 2015-10-08T05:25:10.003 回答