iOS Question UDP Socket Broadcast on port X, listen on port Y (solved)

Scott Bartgis

Member
Licensed User
Note: For what it is worth, this works on Android from B4A, but not on iOS from B4i.

My company produces Linux media servers that listen for a UDP broadcasted string on port 3662 and will respond with a UDP packet on port 3661. I have coded up a Broadcast as UDP Socket and Listener as UDPSocket.

B4X:
Sub Class_Globals
    Dim Broadcast As UDPSocket
    Dim Listener As UDPSocket

    Dim BROADCAST_PORT As Int : BROADCAST_PORT = 3662
    Dim REPLY_PORT As Int : REPLY_PORT = 3661
    Dim LISTEN_TIME As Int : LISTEN_TIME = 5 'in seconds

    Dim BROADCAST_MESSAGE As String : BROADCAST_MESSAGE = "ARQFIND ROLLCALL:\x00"
    Dim REPLY_MESSAGE As String : REPLY_MESSAGE = "ROLLCALL REPLY:\n"
End Sub

Sub btnFindServers_Click
     Broadcast.Initialize("Broadcast", BROADCAST_PORT, 1024)
     Listener.Initialize("Listener", REPLY_PORT, 1024)
     Dim Packet As UDPPacket
     Packet.Initialize(BROADCAST_MESSAGE.GetBytes("UTF8"), "255.255.255.255", BROADCAST_PORT)
     Broadcast.Send(Packet)
End Sub

Sub Listener_PacketArrived(Packet As Object)
    Log("Listener_PacketArrived")
    Dim msg As String
    Dim dp As UDPPacket = Packet
    Log(dp.HostAddress)
    msg = BytesToString(dp.Data, dp.Offset, dp.Length, "UTF8")
    Log("ARQFind Response: " & msg)
End Sub
Wireshark and the 20 devices on my network do not show the UDP packet. The log shows in gray text "error sending data". If I change the broadcast IP from 255.255.255.255 to a specific (known) media server IP, I see the UDP packet and the media server responds and the response is processed in Listener_PacketArrived.

Is my broadcast packet not formed correctly? Is UDP broadcasting not allowed in iOS?
 

Scott Bartgis

Member
Licensed User
Using the inline OBJC, I was able to get the broadcast to work! I suspect we need Erel to modify/enhance the iNetwork internal library to expose some of the socket options like broadcastEnable.

Here is the code that worked for me:

B4X:
#If OBJC
#import <netinet/in.h>
#import <sys/socket.h>
#import <unistd.h>
#import <arpa/inet.h>

- (void)sendBroadcastPacket {
    // Open a socket
    int sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sd<=0) {
        NSLog(@"Error: Could not open socket");
        return;
    }
   
    // Set socket options
    // Enable broadcast
    int broadcastEnable=1;
    int ret=setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
    if (ret) {
        NSLog(@"Error: Could not open set socket to broadcast mode");
        close(sd);
        return;
    }
   
    // Since we don't call bind() here, the system decides on the port for us, which is what we want.   
   
    // Configure the port and ip we want to send to
    struct sockaddr_in broadcastAddr; // Make an endpoint
    memset(&broadcastAddr, 0, sizeof broadcastAddr);
    broadcastAddr.sin_family = AF_INET;
    inet_pton(AF_INET, "255.255.255.255", &broadcastAddr.sin_addr); // Set the broadcast IP address
    broadcastAddr.sin_port = htons(3662); // Set port 3662
   
    // Send the broadcast request, ie "Any upnp devices out there?"
    char *request = "ARQFIND ROLLCALL:\x00";
    ret = sendto(sd, request, strlen(request), 0, (struct sockaddr*)&broadcastAddr, sizeof broadcastAddr);
    if (ret<0) {
        NSLog(@"Error: Could not open send broadcast");
        close(sd);
        return;       
    }

    close(sd);
}
#End If
 

pedrocam

Member
Licensed User
Hi, I am also unable to send udp packets in B4i, while in B4a I was able. Can you explain how to use your code? is this java?
 
Top