How can I set up an UDP Listener at localhost?

Hi,

I’m doing an UDP listener that should listen to all available interfaces on the localhost. For the Windows platform, I can achieve that by setting the ip address to the Winsock predefined INADDR_ANY (which is 0).

I needed to do that because when doing the following:

FIPv4Address ip = FIPv4Address(127,0,0,1);

Would not get me the streaming data. However, when I setup the Socket IP like this:

FIPv4Address ip = FIPv4Address((ULONG)0x00000000);

It does work!

So, I’m a newbie in network programming, so I’m not sure if I’m taking the long way to fix this issue. Maybe the issue is on how my PC network is setup, not sure.

My question is: how can I setup an UDP Listener that will be working on the localhost for all platforms?

So far this is what I got (haven’t tested on any other platform other than Windows so far):

bool UDPReceiver::CreateSocket(){
	GLog->Logf(TEXT("UDPReceiver.CreateSocket: Creating UDP Socket listener at port: %d"), ListenPort);

	//binds ip to INADDR_ANY to listen to all interfaces
	//this only works for windows plataform, since I'm using Winsock INADDR_ANY. 
	//to make this work for other platforms, we need to find out which IP will listen to all interfaces.
#if PLATFORM_WINDOWS
	FIPv4Address ip = FIPv4Address((ULONG)0x00000000);
#elif PLATFORM_MAC
	FIPv4Address ip = FIPv4Address(127,0,0,1);
#elif PLATFORM_IOS
	FIPv4Address ip = FIPv4Address(127,0,0,1);
#elif PLATFORM_WINRT
	FIPv4Address ip = FIPv4Address(127,0,0,1);
#elif PLATFORM_LINUX
	FIPv4Address ip = FIPv4Address(127,0,0,1);
#elif PLATFORM_ANDROID
	FIPv4Address ip = FIPv4Address(127,0,0,1);
#elif PLATFORM_PS4
	FIPv4Address ip = FIPv4Address(127,0,0,1);
#elif PLATFORM_XBOXONE
	FIPv4Address ip = FIPv4Address(127,0,0,1);
#elif PLATFORM_HTML5
	FIPv4Address ip = FIPv4Address(127,0,0,1);
#else
	FIPv4Address ip = FIPv4Address(127,0,0,1);
#endif
	UDPSocket = FUdpSocketBuilder(TEXT("UDP Socket"))
		.AsNonBlocking()
		.AsReusable()
		.BoundToAddress(ip)
		.BoundToPort(ListenPort)
		.WithMulticastLoopback();

    // This doesn't work for Winsock at least. In order to get the error, we should be calling the Winsock WSAGetLastError() right after the bind() function in the SocketBSD.cpp:34
	ESocketErrors error = SocketSubsystem->GetLastErrorCode();
	if (UDPSocket == nullptr)
	{
		SocketSubsystem->DestroySocket(UDPSocket);
		UDPSocket = nullptr;
		GLog->Logf(TEXT("UDPReceiver.CreateSocket: Failed to create unicast socket on localhost: %d, with error code: %d"), ListenPort, (int32) error);
		return false;
	}
	return true;
}

Thank you!

After some more tests, I’m using FIPv4Address::Any assuming that it will work for all platforms.

So the code now is:

	UDPSocket = FUdpSocketBuilder(TEXT("XSens UDP Socket"))
		.AsNonBlocking()
		.AsReusable()
		.BoundToAddress(FIPv4Address::Any)
		.BoundToPort(MVNStudioPort)
		.WithMulticastLoopback();

Yep, this will work. On most operating systems it will create a listen socket for the specified port number on any local network interface. On some operating systems it may only use the default network interface.

Please note that the Networking module is in an experimental state and was mainly written to make life a little easier since the Socket module is somewhat cumbersome to use. I am planning to refactor and heavily extend it this summer (i.e. IPv6 support), so there’s a chance your code may break. We will provide upgrade notes when the time arrives - just something to look out for!

Awesome. Thank you, gmpreussner!

Yes, I’ve read in other answers that you replied that the Networking module will be upgraded and we should be treating it with care.

Will be waiting for this update anxiously :slight_smile: