2.1.2.2 /inet/udp

The server and client programs that use UDP are almost identical to their TCP counterparts; only the protocol has changed. As before, it does matter which side starts first. The receiving side blocks and waits for the sender. In this case, the receiver/client has to be started first:

# Server
BEGIN {
  print strftime() |& "/inet/udp/8888/0/0"
  close("/inet/udp/8888/0/0")
}

The receiver is almost identical to the TCP receiver:

# Client
BEGIN {
  print "hi!" |& "/inet/udp/0/localhost/8888"
  "/inet/udp/0/localhost/8888" |& getline
  print $0
  close("/inet/udp/0/localhost/8888")
}

In the case of UDP, the initial print command is the one that actually sends data so that there is a connection. UDP and “connection” sounds strange to anyone who has learned that UDP is a connectionless protocol. Here, “connection” means that the connect() system call has completed its work and completed the “association” between a certain socket and an IP address. Thus there are subtle differences between connect() for TCP and UDP; see the man page for details.5

UDP cannot guarantee that the datagrams at the receiving end will arrive in exactly the same order they were sent. Some datagrams could be lost, some doubled, and some could arrive out of order. But no overhead is necessary to accomplish this. This unreliable behavior is good enough for tasks such as data acquisition, logging, and even stateless services like the original versions of NFS.


Footnotes

(5)

This subtlety is just one of many details that are hidden in the socket API, invisible and intractable for the gawk user. The developers are currently considering how to rework the network facilities to make them easier to understand and use.