Master The Pico WiFi: UDP For Speed
Written by Harry Fairhead & Mike James   
Monday, 27 November 2023
Article Index
Master The Pico WiFi: UDP For Speed
Sending data

What is the simplest of the TCP protocols? Answer UDP - it's error- prone, but fast. This is an extract from our latest book on the Pico in C.

Master the Raspberry Pi Pico in C:
WiFiwith lwIP & mbedtls

By Harry Fairhead & Mike James

picomaster360

Buy from Amazon.

Contents

       Preface

  1. The Pico WiFi Stack
  2. Introduction To TCP
          Extract:
    Simplest HTTP Client
  3. More Advanced TCP
  4. SSL/TLS and HTTPS
          Extract:
    Simplest HTTPS Client
  5. Details of Cryptography
          Extract:
    Random Numbers NEW!!
  6. Servers
  7. UDP For Speed
          Extract: 
    Basic UDP
  8. SNTP For Time-Keeping
  9. SMTP For Email
  10. MQTT For The IoT

    Appendix 1 Getting Started In C

<ASIN:B0C247QJLK>

 

The UDP (User Datagram) protocol is very different from the more usual TCP (Transmission Control Protocol) connection. UDP is very basic. There is no error correction and no guarantee that datagrams, i.e. packets, will arrive in the order they were sent. All you get is a checksum error detection mechanism that lets you detect any corruption in the data the datagram is carrying. Using IPv4 the data in a datagram is limited to 65,507 bytes, but this limit can be exceeded using IPv6. UDP can also broadcast datagrams simultaneously to as many clients as care to receive them.

After this description you may be wondering why anyone would consider using UDP in preference to TCP. The simple answer is speed. There are few overheads to UDP and it is ideal for sending fast packets of data, as long as packet loss and order don’t matter or can be engineered to not matter. It is the basis for a number of other fast simple protocols such as DHCP (Dynamic Host Configuration Protocol), DNS (Domain Name System) and NTP (Network Time Protocol) and is used in audio and video applications to implement streams of data.

Basic UDP

A UDP packet is very simple. The usual IP header is used and its payload is a UDP datagram. This has a 32-bit header which has the format:

bytes

 

0, 1

Source port number

2, 3

Destination port number

4, 5

Length of data payload including header

6, 7

Checksum

The source port number and checksum are optional and often set to zero and ignored. The length gives the total length of the payload including the header and hence has to be 8 or larger. The largest packet that can be sent is set by the use of a 16-bit value but it is actually smaller than you might expect due to the need to accommodate the IP header.

For IPv4 the largest UDP packet is 65,507 bytes. The checksum field holds a checksum for all of the data, the header and the IP header and it is used for optional error checking.

There are a range of standard port numbers that are used for particular tasks as is the case for TCP. For example, port 123 is used for SNTP and should be avoided for other purposes. Ports above 49152 are not standardized and can be used for anything. Of course, you still have to avoid collisions between different applications. One approach is to use a random assignment of port numbers with the server informing the client of the port in use by some other standard protocol.

UDP Server

A UDP server sends datagrams to another machine specified by IP address and port number. The other machine has to be ready to receive UDP packets, if not the packets are just lost as there is no checking that they have been correctly delivered. In this sense a UDP server isn’t really a server as it doesn’t allow a client to connect in any sense and it is simply a source of packets.

The basic operation of raw UDP is the same as for TCP. There is a PCB, Protocol Control Bock, that you have to initialize and there are functions to set the PCB up and to send and receive datagrams.

To create a UDP PCB we use:

struct udp_pcb *pcb = udp_new();

This has to be bound to an IP address and a port and these are used to determine which network interface is used to send the datagram. You can use IP_ADDR_ANY to use any available interface:

udp_bind(pcb, IP_ADDR_ANY, 8080);

The port used, 8080, isn’t typically used for UDP, but it has a higher probability of working through firewalls. If this program doesn’t work on a particular machine then it is almost certain that it is a firewall rule that is blocking it or the lack of a rule to allow it. If you specify a 0 for port it will automatically bind to a random port between UDP_LOCAL_PORT_RANGE_START and UDP_LOCAL_PORT_RANGE_END.

There are a number of ways of specifying the destination address, but storing it in the PCB follows the method that TCP uses:

ip_addr_t ip;
IP4_ADDR(&ip, 192, 168, 11, 101);
udp_connect(pcb,&ip,8080);

This doesn’t cause anything to happen on the network. It simply stores the information in the PCB. Notice that the remote port doesn’t have to be the same as the source port. If the remote machine needs to send datagrams back then, by default, it will either use the source port if specified or the remote port otherwise. There is a disconnect function:

udp_disconnect(pcb)

but all this does is to zero the fields in the PCB – there is no sense in which a UDP client and server are connected they simply exchange datagrams.



Last Updated ( Monday, 27 November 2023 )