.NET Networking Sockets API

Introduction to .NET Sockets

The .NET Framework provides a robust and flexible set of classes for network communication using sockets. Sockets are the fundamental building blocks for network programming, allowing applications to send and receive data across a network using various protocols such as TCP and UDP.

The primary namespace for socket programming in .NET is System.Net.Sockets. This namespace offers classes that abstract the complexities of underlying operating system socket APIs, making it easier for developers to create network-aware applications.

Key features include:

Core Socket Classes

Socket Class

The Socket class represents a network endpoint and provides methods for sending and receiving data. It is the core class for low-level socket operations.

Key members:

  • Socket(AddressFamily, SocketType, ProtocolType): Constructor to create a new socket.
  • Bind(EndPoint): Associates the socket with a local endpoint.
  • Listen(): Puts a socket into listening mode for incoming connection requests.
  • Accept(): Accepts an incoming connection attempt and returns a new Socket object.
  • Connect(EndPoint): Establishes a connection to a remote host.
  • Send(byte[]): Sends data over the socket.
  • Receive(byte[]): Receives data from the socket.
  • Close(): Releases the socket's resources.

For asynchronous operations, consider methods like BeginConnect, EndConnect, BeginSend, EndSend, etc.

EndPoint and Derived Classes

The EndPoint class is an abstract base class that represents a network endpoint. Concrete implementations are used to specify addresses and ports.

  • IPEndPoint: Represents an endpoint for TCP/IP and UDP communication, consisting of an IP address and a port number.
  • SocketAddress: A more low-level representation of an address.

Example:

var endpoint = new IPEndPoint(IPAddress.Parse("192.168.1.100"), 12345);

SocketException

This exception is thrown for socket-related errors. It provides an ErrorCode property to identify the specific error.

Common Usage Scenarios

TCP Server Example (Conceptual)

A TCP server listens for incoming connections, accepts them, and then exchanges data with the client.


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

// ... in a method ...

// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

// Bind the socket to the local endpoint and listen for incoming connections.
try {
    IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 11000);
    listener.Bind(localEndPoint);
    listener.Listen(100); // Maximum number of queued connections

    Console.WriteLine("Waiting for connections...");
    Socket handler = await listener.AcceptAsync(); // Asynchronous accept

    // Receive data
    byte[] bytes = new byte[1024];
    int bytesRec = await handler.ReceiveAsync(bytes, SocketFlags.None);
    string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);
    Console.WriteLine($"Received: {data}");

    // Send data back
    byte[] msg = Encoding.ASCII.GetBytes("Message received");
    await handler.SendAsync(msg, SocketFlags.None);

    handler.Close();
} catch (Exception e) {
    Console.WriteLine(e.ToString());
} finally {
    if (listener != null) listener.Close();
}
            

UDP Client Example (Conceptual)

A UDP client sends datagrams to a specified server and can optionally listen for responses.


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

// ... in a method ...

// Data buffer for receiving data.
byte[] bytes = new byte[1024];

// Connect to a remote device.
try {
    IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("192.168.1.100"), 11000);
    using (Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
    {
        // Send data to remote device
        byte[] msg = Encoding.ASCII.GetBytes("This is a test message");
        await sender.SendToAsync(msg, SocketFlags.None, remoteEP);

        // Optional: Receive response
        EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
        int bytesRec = await sender.ReceiveFromAsync(bytes, SocketFlags.None, remote);
        Console.WriteLine($"UDP Server replied: {Encoding.ASCII.GetString(bytes, 0, bytesRec)}");
    }
} catch (Exception e) {
    Console.WriteLine(e.ToString());
}
            

Advanced Topics and Considerations