简体   繁体   English

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

[英]Send UDP message from Linux C to many Android phones

Rewritten to try and be clear on what I need. 重写以尝试明确我的需求。

My goal is to duplicate the function of a device made by Digital Yacht in an embedded Intel Edison processor running C and Linux. 我的目标是在运行C和Linux的嵌入式Intel Edison处理器中复制Digital Yacht制造的设备的功能。 The device sends via UDP to phone apps such as iRegatta and others. 设备通过UDP发送到iRegatta等电话应用程序。 To set up the app, only the port number is entered. 要设置该应用程序,只需输入端口号。 No ip address is entered in UDP mode on the app. 应用程序未在UDP模式下输入IP地址。 I thought this was trivial but the experts here so far have said it is impossible so it must not be trivial. 我以为这是微不足道的,但到目前为止,这里的专家都说这是不可能的,因此一定不要微不足道。 Perhaps that is why with all my hours of reading I cannot find an example. 也许这就是为什么在我所有的阅读时间里都找不到一个例子。 I am being voted down because, I am told, that what I am trying to do it impossible but it is not as it is done. 有人告诉我,我被否决是因为,我试图做的事情不可能实现,但事实并非如此。 I don't know how it is done, which is why I came to experts here. 我不知道它是如何完成的,这就是为什么我来到这里的专家。

I want to send nmea messages that might look like this: 我想发送可能看起来像这样的nmea消息:

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

and I want any number of random Android phones to be able to receive them with the appropriate app. 我希望任意数量的Android手机都能通过相应的应用接收它们。 There are many apps that can be set up to receive UDP data where you just specify a port number. 您可以在仅指定端口号的情况下设置许多应用程序以接收UDP数据。 There is no ip address involved in the setup of the apps. 应用程序的设置中没有IP地址。 Also, I do not wish to receive anything from the Android phones. 另外,我也不希望收到来自Android手机的任何信息。 This is one way and no ability to re-transmit so if a message does not get there, it has another chance next time. 这是一种方法,没有重新传输的能力,因此,如果一条消息没有到达那里,则下次有另一种机会。 Everything is updated once a second. 一切都会每秒更新一次。

I tried the following and I do not get data in the app. 我尝试了以下操作,但未在应用程序中获取数据。 From the comments, I must need to add some kind of router function in my Linux machine. 根据评论,我必须在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);
        }
    }
}

I am not really sure what I need to do. 我不确定我需要做什么。

What you want to do is send a UDP packet to a broadcast IP address. 您要做的是将UDP数据包发送到广播IP地址。 This will send to thing in the subnet. 这将发送到子网中的事物。 eg 10.255.255.255 is the broadcast address for the 10.xxx subnet. 例如10.255.255.255是10.xxx子网的广播地址。 You can also use the global 255.255.255.255 which should also send to your subnet and no router is going to pass that on to another one these days. 您还可以使用全局255.255.255.255,该地址也应发送到您的子网,并且现在没有路由器将其传递给另一个子网。

Also you need to make your socket able to send broadcast messages. 另外,您还需要使套接字能够发送广播消息。 In particular you need the option SO_BROADCAST set. 特别是您需要设置SO_BROADCAST选项。 The following is specifically Windows because of the BOOL . 由于BOOL缘故,以下是Windows。 Its presumably an int for most platforms. 它可能是大多数平台的int。

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

Also you can't use send() for a UDP socket unless its "connected", so you should use sendto() and use the broadcast address. 同样,除非UDP套接字已“连接”,否则您不能对UDP套接字使用send() ,因此您应该使用sendto()并使用广播地址。

To specify an address and port, use need to create a socket address. 要指定地址和端口,请使用需要创建一个套接字地址。

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) );

Note the use of the typecast. 注意类型转换的使用。 This is because sendto takes a sockaddr which is a generic address type, and here we are using an IPV4 address specifically. 这是因为sendto需要一个sockaddr ,它是一种通用地址类型,在这里我们专门使用IPV4地址。 The sockaddr_in maps onto the sockaddr sockaddr_in映射到sockaddr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM