Skip to main content

Networking Core

TinyCLR's networking stack implements a subset of Microsoft's standard System.Net.Sockets API. Most .NET socket code runs on TinyCLR with little or no modification — including TCP/UDP sockets, DNS lookups, and TLS. Familiarity with the standard System.Net.Sockets.Socket class transfers directly.

This page covers the common pieces — MAC addresses, IP assignment, sockets, DNS, mDNS — that apply regardless of the underlying transport (Ethernet, WiFi, cellular, PPP).

MAC addresses​

Before using SITCore's built-in PHY or the ENC28-based Ethernet, you must set a MAC address — otherwise an exception is raised on enable. For internal testing, any locally-administered MAC will work; for shipped products, you need a valid, unique MAC.

If you don't have access to a registered OUI, sensible options are:

  • Use a MAC address from a decommissioned computer or network card.
  • Use an online MAC generator (acceptable for one-offs, not for production volumes).
warning

Two devices with the same MAC address on the same local subnet break each other — neither will communicate reliably. Plan for unique MACs on every shipped unit.

The WINC1500 WiFi module ships with a manufacturer-assigned unique MAC. That MAC is used by default, but you can override it if you need to.

IP assignment​

TinyCLR supports both static and dynamic IP. With either method, a NetworkAddressChanged event fires once an IP is available so your application can react:

networkController.NetworkAddressChanged += NetworkController_NetworkAddressChanged;

void NetworkController_NetworkAddressChanged(NetworkController sender, NetworkAddressChangedEventArgs e) {
var ipProperties = sender.GetIPProperties();
}
tip

Static IP addressing is not available on PPP connections.

Static IP​

Set the address, mask, gateway, and DNS servers manually:

networkInterfaceSetting.DhcpEnabled = false;
networkInterfaceSetting.Address = new IPAddress(new byte[] { 192, 168, 1, 122 });
networkInterfaceSetting.SubnetMask = new IPAddress(new byte[] { 255, 255, 255, 0 });
networkInterfaceSetting.GatewayAddress = new IPAddress(new byte[] { 192, 168, 1, 1 });
networkInterfaceSetting.DnsAddresses = new IPAddress[] {
new IPAddress(new byte[] { 75, 75, 75, 75 }),
new IPAddress(new byte[] { 75, 75, 75, 76 }),
};

Dynamic IP​

A single setting enables DHCP. The device tries to lease an IP from a DHCP server first; if that fails, it falls back to AutoIP (self-assigning a link-local address). Both paths can take a few seconds — wait for the NetworkAddressChanged event to know when the IP is ready.

networkInterfaceSetting.DhcpEnabled = true;
tip

AutoIP addresses always fall in the 169.254.x.x range. Check the assigned address against that range to know whether DHCP succeeded or AutoIP took over.

TCP and UDP sockets​

TCP and UDP are accessed through the standard System.Net.Sockets.Socket API. Most desktop .NET examples for these protocols work with little or no change on TinyCLR.

TCP​

using System.Net;
using System.Net.Sockets;
using System.Text;

using var s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

try {
var ip = IPAddress.Parse("192.168.1.87");
s.Connect(new IPEndPoint(ip, 80));
s.Send(Encoding.UTF8.GetBytes("I am SITCore\r\n"));
}
catch {
// Connection or send failed.
}

UDP​

using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
var ip = new IPAddress(new byte[] { 192, 168, 1, 87 });
var endPoint = new IPEndPoint(ip, 2000);

socket.Connect(endPoint);

byte[] bytesToSend = Encoding.UTF8.GetBytes(msg);

while (true) {
socket.SendTo(bytesToSend, bytesToSend.Length, SocketFlags.None, endPoint);

while (socket.Poll(2_000_000, SelectMode.SelectRead)) {
if (socket.Available > 0) {
byte[] inBuf = new byte[socket.Available];
var recEndPoint = new IPEndPoint(IPAddress.Any, 0);
socket.ReceiveFrom(inBuf, ref recEndPoint);

// Ignore packets that didn't come from the address we're talking to.
if (!recEndPoint.Equals(endPoint))
continue;

Debug.WriteLine(new string(Encoding.UTF8.GetChars(inBuf)));
}
}

Thread.Sleep(100);
}

DNS​

Resolve a hostname to an IP address with Dns.GetHostEntry:

using System;
using System.Net;

var hostEntry = Dns.GetHostEntry(hostName);

if (hostEntry != null && hostEntry.AddressList.Length > 0) {
IPAddress remoteIpAddress = null;
for (int i = 0; i < hostEntry.AddressList.Length; i++) {
if (hostEntry.AddressList[i] != null) {
remoteIpAddress = hostEntry.AddressList[i];
break;
}
}

if (remoteIpAddress == null)
throw new Exception("No usable address returned for " + hostName);
}
else {
throw new Exception("Server not found: " + hostName);
}

mDNS​

Multicast DNS lets devices discover each other on the local network without a central DNS server. Not all client operating systems include an mDNS responder — macOS and recent Windows do; some Linux distributions require avahi.

networkInterfaceSetting.MulticastDnsEnable = true;

networkController.Enable();

MulticastDns.Start("MyServer", TimeSpan.FromHours(1)); // TTL: 1 hour

Once started, the device responds to lookups for MyServer.local on the local subnet.

Secure sockets (TLS)​

TLS 1.2 is natively supported and integrates with the standard socket API. See the TLS page for the full reference.

API reference​

NamespaceDescription
GHIElectronics.TinyCLR.NetworkingSocket, DNS, and mDNS networking classes
GHIElectronics.TinyCLR.Devices.NetworkNetwork interface controller (MAC address, IP config)