I recently wanted to write a swift app to listen to and consume UDP broadcast (multicast) messages that a hardware device uses but found the documentation says this is not supported at any level of Apple SDKs and you have to drop down to posix and that those calls are hard to get right (ref: TN3151: Choosing the right networking API | Apple Developer Documentation ).
So I hope that whatever new unified thing is built fixes this hole in all the current various higher level offerings from Apple.
Nope. Seemed originally for server side use cases and I never looked at it again (since I don’t do that). Seemed pretty heavy (lot of of stuff that isn’t needed for the little utility I was writing). Looking at it now I see that it’s broken into a number of pieces and maybe a small subset could be linked in.
I’ve only been looking at the native client application level frameworks.
I notice that NIO isn’t mentioned in the tech note I referenced. That reinforced my impression that it was a server side thing and not really for native apps.
I’ll look again. Thanks for the idea.
That said, I still think that if a new network framework is going to be made to update and consolidate all the too many deprecated-soon existing ones then it ought to plug this hole.
Agreed, there are several different use cases for broadcast (multicast is covered in that TechNote, I think) which could make sense to include in new networking packages.
Since it might spark others to chime in with their similar use cases, is there anything more you can say about the shape of what broadcast messages you're trying to consume and what sort of API shape would be the most intuitive there?
e.g. today multicast is delivered as a per-message callback with some message size considerations and very little in the way of backpressure. Would that make sense for broadcast? Dropping packets if you're not consuming them fast enough seems true to the underlying transport, but it also seems nice to avoid dropping packets that have actually made it to the interface.
I backed a 3D Print Sensor on Kickstarter and the unit broadcasts its current readings via UDP.
Their sample code is written in C# for .NET (included below) and I wanted to translate it to Swift and maybe make some UI for it beyond the command line logging.
Reading the Networking tech note and seeing all the deprecated UDP supporting API, it seems pretty clear this isn't really supported easily on macOS X (I've not done any UDP before so there is already a learning curve). That's sad.
UDP is a fundamental protocol of the internet and local networking and it really seems like it should be well supported along with the more popular TCP/IP etc.
I'm under the impression that UDP is also used for some multi-player games, but maybe they use multicast? As I noted above, I'm new to UDP so lots to learn still.
C# sample code provided by the hardware maker
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class UdpReceiver
{
static void Main(string args)
{
// Define the UDP broadcast port and local endpoint.
int listenPort = 1234;
UdpClient udpListener = new UdpClient(listenPort);
// Enable listening to broadcast messages.
udpListener.EnableBroadcast = true;
Console.WriteLine($"3DPS Data Logger v1.0");
Console.WriteLine($"Listening for UDP broadcast messages on port {listenPort}...");
try
{
while (true)
{
// Receive data from the UDP broadcast.
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, listenPort);
byte[] receivedBytes = udpListener.Receive(ref remoteEndPoint);
// Convert the received bytes to a string.
string receivedMessage = Encoding.UTF8.GetString(receivedBytes);
// Display the received message in the console.
Console.WriteLine(receivedMessage);
// Create a new file name based on the current day of the week
string date = DateTime.Now.ToString("M_d_yyyy");
string filePath = string.Format("LogFile_{0}.csv", date);
DateTime currentDateTime = DateTime.Now;
string formattedDate = currentDateTime.ToString("HH:mm:ss");
string logData = formattedDate + "," + receivedMessage;
Console.WriteLine(logData);
using (StreamWriter writer = new StreamWriter(filePath, append: true))
{
writer.WriteLine(logData);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
udpListener.Close();
}
}
On the UDP receiver side it shouldn't matter if the sender used broadcast or not, so as to macOS you could use either network framework or sockets to receive those broadcasts.