The UDP socket example is provided at this link here.
The initial part of the code on the server side is to create a UDP socket. Note the type field which is set to SOCK_DGRAM (as opposed to SOCK_STREAM in a stream socket connection).
if (0 > (sock_udp_server = socket(AF_INET, SOCK_DGRAM, 0))) {
printf(“Unable to create a socket\n”);
exit(0);
}
If the above code is successful, a udp socket is created and a socket file descriptor (the number denoting the socket (in sock_udp_server)) is provided to the application.
The server code goes ahead and binds to a specific UDP port and a specific IP address. The IP address in the current example is the localhost address and the PORT is provided as 55555.
sock_addr->sin_family = AF_INET;
sock_addr->sin_port = htons(UDPPORT);
sock_addr->sin_addr.s_addr = inet_addr(“127.0.0.1”);
if (0 != (bind(sock_udp_server, (struct sockaddr *)sock_addr, sizeof(struct sockaddr_in)))) {
printf(“unable to bind the socket\n”);
goto end2;
}
If Bind API is successful, the server waits for incoming data packets. This is in contrast to the stream socket connection wherein, the server would wait for incoming client connections via “listen” and “accept” APIs.
the output of the “ss -ul shell command” provides the below output for the UDP server at the end of bind stage
State Recv-Q Send-Q Local Address:Port Peer Address:Port
UNCONN 12288 0 127.0.0.53%lo:domain 0.0.0.0:*
UNCONN 0 0 0.0.0.0:bootpc 0.0.0.0:*
UNCONN 0 0 127.0.0.1:55555 0.0.0.0:*
On the client side, the client application establishes a socket and tries to send packet to the server address. This is in contrast to a stream socket connection, wherein the client stream connection code attempts to connect to the server via the “connect API”.
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
/* Part 2 – fill the server structure for the specific interface */
server_addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
if (server_addr == NULL) {
printf(“Unable to allocate memory\n”);
goto end;
}
server_addr->sin_family = AF_INET;
server_addr->sin_addr.s_addr = inet_addr(“127.0.0.1”);
server_addr->sin_port = htons(PORT);
The server receives the packet that is sent by a client and is able to obtain the client address to respond to. This is shown below
while (1) {
memset(buffer, 0, sizeof(buffer));
num_of_bytes = recvfrom(sock_udp_server, buffer, sizeof(buffer), 0, (struct sockaddr *)client_addr, &length);
The server can later send data to the client address stored in the client_addr structure as shown below
num_of_bytes = sendto(sock_udp_server, buffer, sizeof(buffer), 0, (struct sockaddr *)client_addr, length );
The output of ss when data transaction is enabled is not different from when the bind call on the server code successfully completed. It is shown below
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
udp UNCONN 30720 0 127.0.0.1:55555 0.0.0.0:*
The peer address is not filled in an UDP connection in contrast to a TCP connection wherein a specific IPaddress:port combination is present in the Peer Address: Port column as TCP is a connection oriented protocol as opposed to UDP which is a connectionless protocol
Socket Based IPC- Unix Domain Sockets
Pingback: UDP Server/client example | Hitch Hiker's Guide to Learning