How can I create a UDP server with static IP?

Hi.

I have wrote the code as follows:

appudData.cString[0x00] = 'H';
appudData.cString[0x01] = 'a';
appudData.cString[0x02] = 'l';
appudData.cString[0x03] = 'l';
appudData.cString[0x04] = 'o';
appudData.cString[0x05] = 0x00;
                
FreeRTOS_sendto( xSocket,
           &appudData.cString,
           strlen( appudData.cString ),
           0,
           &xDestinationAddress,
           sizeof(xDestinationAddress ) );
vTaskDelay(2000 / portTICK_PERIOD_MS);

But data transmission only happens once or twice when the hardware is powered up:

I have debuted the code to determine any problems, but code is always sending the data every 2 seconds.

Obviously I have enabled the LLMNR as follows in the FreeRTOSIPConfigDefaults.h file:

#ifndef ipconfigUSE_LLMNR
	/* Include support for LLMNR: Link-local Multicast Name Resolution (non-Microsoft) */
	#define ipconfigUSE_LLMNR					( 1 ) //Enable LMNR
#endif

Hi.

I have LLMNR enabled, but pinging the device name doesn’t work.

Obviously I have enabled the LLMNR as follows in the FreeRTOSIPConfigDefaults.h file:

Oops, the file FreeRTOSIPConfigDefaults.c is part of the library and should never used for personal changes. In stead you can edit your FreeRTOSIPConfig.h file, and add:

    #define ipconfigUSE_LLMNR     ( 1 )

Now you will also have to write the following function:

const char *pcMyName = "PLCWorkerETH";

BaseType_t xApplicationDNSQueryHook( const char *pcName )
{
BaseType_t xReturn = pdFAIL;

    if( strcasecmp( pcName, pcMyName ) == 0 )
    {
        xReturn = pdPASS;
    }
	return xReturn;
}

And also please make sure that LLMNR is enabled in your Windows.

Note that LLMNR is considered unsafe. The IPv6/multi branch has already mDNS, which can be used for local lookup’s, in stead of LLMNR or NBNS. mDNS should also be added to the main branch, when there is time.

I wonder how “Advanced IP scanner” gets the name that belongs to an IP-address? Is that based on the MAC-address? … yes, it looks like it.

Have you already tried to send a UDP broadcast message to 192.168.0.255 and open a UDP socket on a well-known port number to receive it?

Thanks a lot for the suggestion.

Yes, I had noticed the xApplicationDNSQueryHook function and I had taken as an example the one in the iot_demo_freertos.c file:

I imagine it is due to what is below in the aws_demo_network_addr.c file:

#if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 )

    const char * pcApplicationHostnameHook( void )
    {
        /* This function will be called during the DHCP: the machine will be registered
         * with an IP address plus this name. */
        return clientcredentialIOT_THING_NAME; // (It's PLCWorkerETH)
    }

#endif

Despite its recommendation, the problem still continues, with only two times the data reaching 224.00.252. More data arrives, but after several minutes

Yes, I was thinking of using another IP address (the one of my PC with a tool that allows to open UDP sockets), to check if the same problem happens, it could be with 192.168.0.255.

The problem is that the segment 192.168.0.xx can vary in another user, for example it can be 192.168.10.xxx. Although of course, with the dynamic IP supplied by the router, the MCU can know the correct segment

Sending data to my PC or address 192.168.0.255 works correctly:

Something special has the address 242.0.252 which only rarely supports data from my hardware.

I would think that using 192.168.0.255 would be the solution, but from C# you cannot open a multicast socket there. I’m going to try to open a normal UDP socket in that address, also I should also try to use another multicast address other than 254.0.0.252

242.0.0.252 is a ‘Special’ address in the Multi-cast address range. NO ONE should ‘have’ that address, but many units can listen for it. Note that 242.0.0.252 is in the range of ‘Well Known’ Multi-cast addresses, so the functioning of any host that listens for that address is defined by the standards (it is for LLMNR).

I am not sure if ‘sockets’ are the right approach to talking to that port, as you don’t really set up a ‘link’ to a multi-cast port, as there isn’t necessarily a single host you are talking to, but there may be multiple hosts on that IP address that decide if they know how to answer that request, so you might get zero, one, or multiple answers back from your message.

1 Like

The following code done in C# has worked, hope it is useful for someone else:

int PORT = 7000;
udpClient = new UdpClient();
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, PORT));

...

 private async Task<string> recepcionDatos()
 {
     try
     {
                var from = new IPEndPoint(0, 0);
                while (true)
                {
                        var recvBuffer = udpClient.Receive(ref from);
                        string result = Encoding.UTF8.GetString(recvBuffer);
                        if (result != null && result.Length > 0)
                        {
                            return result;
                        }
                }
         }
        ....
}

It can’t get the message from my PC, but from other PCs it works fine, possibly it’s some kind of security, but the next step is to test this same code for an app developed for Android (Xamarin), I hope it works there too.

And I used the address 192.168.0.255 as suggested by @htibosch

Why not have all your devices that are going to participate in your service just listen and respond to a multicast message call it ‘whose there.!wellknown.ip’, with their own IP addresses back to the sender. The sender then reaches out and creates connections to each of their IP’s individually. Members can come and go then - you have a time out that if a heart beat message is no longer responded to then your done.