A useful abstraction for programming network applications is that of a network socket. The notion of a socket groups together the individual elements required to communicate between two network nodes: the local IP address and port (explained in the next section), the remote IP address and port, and which protocol should be used to communicate between them (for example, UDP, TCP, or, in rare cases, raw IP). In addition to just grouping configuration information, a standard API, known as the Berkeley Sockets API, has been developed and is widely used across many programming languages. On Windows operating systems, this API has continued to evolve (as Winsock) and is fully supported in .NET through the System.Net namespace. A version of this namespace is provided by the .NET Micro Framework and is discussed extensively in the section titled "TCP" later in this chapter.
We've already described the function of IP addresses as identifying a device on a network. To allow more than one program or process to communicate (as a client or server) at that address, the idea of a port is introduced. A port is a number used to associate network data with a particular application. In the realms of TCP and UDP, many port numbers have specific meaning (that is, they are typically associated with specific services), such as port 80 (Web servers, or HTTP), and ports 20 and 21 (FTP). There is also a range of port numbers, the socalled ephemeral ports, 49152 through 65535, which is generally reserved for automatic assignment by the IP stack (internal software)-this is vendor-specific, so please check the data sheet for the device you are using.
The User Datagram Protocol (UDP) is often considered an unreliable and connectionless protocol and is useful for sending small messages across a network with no guarantee of delivery or arrival order. UDP is known for being lightweight and fast, but also error prone because messages can be lost in transmission or arrive more than once. There is also no built-in congestion avoidance or throttling that prevents a network from becoming saturated and inefficient. It operates at Layer 4 (transport) in the OSI model. The DNS service we discussed earlier operates using UDP messages, as do many streaming services, such as Voice over Internet Protocol (VoIP). In the case of DNS, if a packet is dropped (either request or response), the client can simply wait for a timeout period and reissue it. In the case of VoIP, dropping a packet merely affects sound quality. If you require more reliability or guaranteed ordering, then you will need to develop your own application-layer protocol or consider using TCP (explained in the next section).
One of the additional advantages of using UDP is the ability to broadcast or multicast data across the network. In broadcasting (Figure 6-2), every node on the network will (theoretically) receive the message.
Figure 6-2: Broadcast routing.
In multicasting (Figure 6-3), only nodes that have joined a specific multicast group will receive the message.
Figure 6-3: Multicast routing.
There are many restrictions on the address ranges that can be used for either of these purposes, so be sure to do your research before using them.
UDP messages are sent in discrete units called packets. Packets consist of a fixed-size header plus variable-length data. Fortunately, the .NET Micro Framework takes care of the details of making sure the packets are properly formatted and that the headers are properly populated. There is a theoretical upper bound on the amount of data that can be sent in a single packet, 65507 bytes. We derive this value by taking the maximum size of an IP packet (65536) and accounting for the fixed headers of IP (20 bytes) and UDP (8 bytes). However, various IP stack implementations may impose additional restrictions on the amount of data that can be sent in a single packet; refer to the vendor-specific documentation for details.
Examples of how to use UDP support in the .NET Micro Framework are provided later in this chapter, in the section "Updating HQ Using UDP."
In contrast to UDP, the Transmission Control Protocol (TCP) is considered reliable and connection-oriented. That is, this is also a Layer 4 protocol (with some aspects residing in Layer 5) but addresses many of the issues identified with the simpler UDP approach, such as ensuring message delivery, in order, without duplicates, while preventing network congestion. These features come at an expense, of course: messages often take longer to reach their destination because a number of protocol-level messages are being exchanged (for example, handshakes and acknowledgements), and it is also not possible to broadcast or multicast-communication is always with a single endpoint or unicast (depicted in Figure 6-4).
Figure 6-4: Unicast routing.
To achieve this, TCP uses the concept of a connection. This can be thought of as a virtual circuit or like a telephone conversation between two people. Once such a connection is established, the messages that flow between the two nodes are considered to be a stream of data, a distinction that will become clear when we start programming them.