Datagram Socket (UDP)
The figure below reproduces a diagram that introduces sample code using the typical socket functions for a UDP client-server application. The example uses the Micrium proprietary socket API function calls. A similar example could be written using the BSD socket API.
The code in the listing below implements a UDP server. It opens a socket and binds an IP address, listens and waits for a packet to arrive at the specified port.
Datagram Server (UDP Server)
Listing - Datagram Server
#include <Source/net_cfg_net.h>
#include <Source/net_sock.h>
#include <Source/net_app.h>
#include <Source/net_util.h>
#define UDP_SERVER_PORT 10001
#define RX_BUF_SIZE 15
#ifdef NET_IPv4_MODULE_EN
void App_UDP_ServerIPv4 (void)
{
NET_SOCK_ID sock;
NET_SOCK_ADDR_IPv4 server_sock_addr_ip;
NET_SOCK_ADDR_IPv4 client_sock_addr_ip;
NET_SOCK_ADDR_LEN client_sock_addr_ip_size;
NET_SOCK_RTN_CODE rx_size;
NET_SOCK_RTN_CODE tx_size;
NET_SOCK_DATA_SIZE tx_rem;
CPU_CHAR rx_buf[RX_BUF_SIZE];
CPU_INT32U addr_any = NET_IPv4_ADDR_ANY;
void *p_buf;
CPU_BOOLEAN fault_err;
NET_ERR err;
/* ----------------- OPEN IPV4 SOCKET ----------------- */
sock = NetSock_Open( NET_SOCK_ADDR_FAMILY_IP_V4,
NET_SOCK_TYPE_DATAGRAM,
NET_SOCK_PROTOCOL_UDP,
&err);
if (err != NET_SOCK_ERR_NONE) {
return;
}
/* ------------ CONFIGURE SOCKET'S ADDRESS ------------ */
NetApp_SetSockAddr((NET_SOCK_ADDR *)&server_sock_addr_ip,
NET_SOCK_ADDR_FAMILY_IP_V4,
UDP_SERVER_PORT,
(CPU_INT08U *)&addr_any,
NET_IPv4_ADDR_SIZE,
&err);
switch (err) {
case NET_APP_ERR_NONE:
break;
case NET_APP_ERR_FAULT:
case NET_APP_ERR_NONE_AVAIL:
case NET_APP_ERR_INVALID_ARG:
default:
NetSock_Close(sock, &err);
return;
}
/* ------------------- BIND SOCKET -------------------- */
NetSock_Bind( sock,
(NET_SOCK_ADDR *)&server_sock_addr_ip,
NET_SOCK_ADDR_SIZE,
&err);
if (err != NET_SOCK_ERR_NONE) {
NetSock_Close(sock, &err);
return;
}
fault_err = DEF_NO;
do {
/* ----- WAIT UNTIL RECEIVING DATA FROM A CLIENT ------ */
client_sock_addr_ip_size = sizeof(client_sock_addr_ip);
rx_size = NetSock_RxDataFrom( sock,
rx_buf,
RX_BUF_SIZE,
NET_SOCK_FLAG_NONE,
(NET_SOCK_ADDR *)&client_sock_addr_ip,
&client_sock_addr_ip_size,
DEF_NULL,
DEF_NULL,
DEF_NULL,
&err);
switch (err) {
case NET_SOCK_ERR_NONE:
tx_rem = rx_size;
p_buf = rx_buf;
/* ----- TRANSMIT THE DATA RECEIVED TO THE CLIENT ----- */
do {
tx_size = NetSock_TxDataTo( sock,
p_buf,
tx_rem,
NET_SOCK_FLAG_NONE,
(NET_SOCK_ADDR *)&client_sock_addr_ip,
client_sock_addr_ip_size,
&err);
tx_rem -= tx_size;
p_buf += tx_size;
} while (tx_rem > 0);
break;
case NET_SOCK_ERR_RX_Q_EMPTY:
case NET_ERR_FAULT_LOCK_ACQUIRE:
break;
default:
fault_err = DEF_YES;
break;
}
} while (fault_err == DEF_NO);
/* ------------- FATAL FAULT SOCKET ERROR ------------- */
NetSock_Close(sock, &err); /* This function should be reached only when a fatal ...*/
/* fault error has occurred. */
}
#endif
/*
*********************************************************************************************************
* App_UDP_ServerIPv6()
*
* Description : UDP Echo server:
*
* (a) Open a socket.
* (b) Configure socket's address.
* (c) Bind that socket.
* (d) Receive data on the socket.
* (e) Transmit to source the data received.
* (f) Close socket on fatal fault error.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : none.
*
* Note(s) : none.
*********************************************************************************************************
*/
#ifdef NET_IPv6_MODULE_EN
void App_UDP_ServerIPv6 (void)
{
NET_SOCK_ID sock;
NET_SOCK_ADDR_IPv6 server_sock_addr_ip;
NET_SOCK_ADDR_IPv6 client_sock_addr_ip;
NET_SOCK_ADDR_LEN client_sock_addr_ip_size;
NET_SOCK_RTN_CODE rx_size;
NET_SOCK_RTN_CODE tx_size;
NET_SOCK_DATA_SIZE tx_rem;
CPU_CHAR rx_buf[RX_BUF_SIZE];
void *p_buf;
CPU_BOOLEAN fault_err;
NET_ERR err;
/* ----------------- OPEN IPV6 SOCKET ----------------- */
sock = NetSock_Open( NET_SOCK_ADDR_FAMILY_IP_V6, /* IPv6 Socket family. */
NET_SOCK_TYPE_DATAGRAM, /* Datagram socket. */
NET_SOCK_PROTOCOL_UDP, /* UDP protocol. */
&err);
if (err != NET_SOCK_ERR_NONE) {
return;
}
/* ------------ CONFIGURE SOCKET'S ADDRESS ------------ */
/* Populate the NET_SOCK_ADDR_IP structure for the ... */
/* server address and port, and convert it to ... */
/* network order. */
NetApp_SetSockAddr((NET_SOCK_ADDR *)&server_sock_addr_ip,
NET_SOCK_ADDR_FAMILY_IP_V6,
UDP_SERVER_PORT,
(CPU_INT08U *)&NET_IPv6_ADDR_ANY,
NET_IPv6_ADDR_SIZE,
&err);
switch (err) {
case NET_APP_ERR_NONE:
break;
case NET_APP_ERR_FAULT:
case NET_APP_ERR_NONE_AVAIL:
case NET_APP_ERR_INVALID_ARG:
default:
NetSock_Close(sock, &err);
return;
}
/* ------------------- BIND SOCKET -------------------- */
NetSock_Bind( sock, /* Bind the newly created socket to the address and ... */
(NET_SOCK_ADDR *)&server_sock_addr_ip, /* port specified by server_sock_addr_ip. */
NET_SOCK_ADDR_SIZE,
&err);
if (err != NET_SOCK_ERR_NONE) {
NetSock_Close(sock, &err);
return;
}
fault_err = DEF_NO;
do {
/* ----- WAIT UNTIL RECEIVING DATA FROM A CLIENT ------ */
client_sock_addr_ip_size = sizeof(client_sock_addr_ip);
rx_size = NetSock_RxDataFrom( sock, /* Receive data from any host on port UDP_SERVER_PORT. */
rx_buf,
RX_BUF_SIZE,
NET_SOCK_FLAG_NONE,
(NET_SOCK_ADDR *)&client_sock_addr_ip,
&client_sock_addr_ip_size,
DEF_NULL,
DEF_NULL,
DEF_NULL,
&err);
switch (err) {
case NET_SOCK_ERR_NONE:
tx_rem = rx_size;
p_buf = rx_buf;
do {
/* ------- TRANSMIT RECEIVED DATA TO THE CLIENT ------- */
/* Transmit data to IP address and port of the client. */
tx_size = NetSock_TxDataTo( sock,
p_buf,
tx_rem,
NET_SOCK_FLAG_NONE,
(NET_SOCK_ADDR *)&client_sock_addr_ip,
client_sock_addr_ip_size,
&err);
tx_rem -= tx_size;
p_buf += tx_size;
} while (tx_rem > 0);
break;
case NET_SOCK_ERR_RX_Q_EMPTY:
case NET_ERR_FAULT_LOCK_ACQUIRE:
break;
default:
fault_err = DEF_YES;
break;
}
} while (fault_err == DEF_NO); /* Process more client requests. */
/* ------------- FATAL FAULT SOCKET ERROR ------------- */
NetSock_Close(sock, &err); /* This function should be reached only when a fatal ...*/
/* fault error has occurred. */
}
#endifOpen a datagram socket (UDP protocol).
Populate the
NET_SOCK_ADDR_IPstructure for the server address and port, and convert it to network order.Bind the newly created socket to the address and port specified by
server_sock_addr_ip.Receive data from any host on port
DATAGRAM_SERVER_PORT.Close the socket.
Datagram Client (UDP Client)
The code in the listing below implements a UDP client. It sends a ‘Hello World!’ message to a server that listens on the UDP_SERVER_PORT.
Listing - Datagram Server
#define UDP_SERVER_IP_ADDR "192.168.1.100"
#define UDP_SERVER_PORT 10001
#define UDP_SERVER_TX_STR "Hello World!"
CPU_BOOLEAN TestUDPClient (void)
{
NET_SOCK_ID sock;
NET_IP_ADDR server_ip_addr;
NET_SOCK_ADDR_IP server_sock_addr_ip;
NET_SOCK_ADDR_LEN server_sock_addr_ip_size;
CPU_CHAR *pbuf;
CPU_INT16S buf_len;
NET_SOCK_RTN_CODE tx_size;
NET_ERR err;
pbuf = UDP_SERVER_TX_STR;
buf_len = Str_Len(UDP_SERVER_TX_STR);
sock = NetSock_Open( NET_SOCK_ADDR_FAMILY_IP_V4, (1)
NET_SOCK_TYPE_DATAGRAM,
NET_SOCK_PROTOCOL_UDP,
&err);
if (err != NET_SOCK_ERR_NONE) {
return (DEF_FALSE);
}
server_ip_addr = NetASCII_Str_to_IP(UDP_SERVER_IP_ADDR, &err); (2)
if (err != NET_ASCII_ERR_NONE) {
NetSock_Close(sock, &err);
return (DEF_FALSE);
}
server_sock_addr_ip_size = sizeof(server_sock_addr_ip); (3)
Mem_Clr((void *)&server_sock_addr_ip,
(CPU_SIZE_T) server_sock_addr_ip_size);
server_sock_addr_ip.AddrFamily = NET_SOCK_ADDR_FAMILY_IP_V4;
server_sock_addr_ip.Addr = NET_UTIL_HOST_TO_NET_32(server_ip_addr);
server_sock_addr_ip.Port = NET_UTIL_HOST_TO_NET_16(UDP_SERVER_PORT);
tx_size = NetSock_TxDataTo((NET_SOCK_ID ) sock, (4)
(void *) pbuf,
(CPU_INT16S ) buf_len,
(CPU_INT16S ) NET_SOCK_FLAG_NONE,
(NET_SOCK_ADDR *)&server_sock_addr_ip,
(NET_SOCK_ADDR_LEN) sizeof(server_sock_addr_ip),
(NET_ERR *)&err);
NetSock_Close(sock, &err); (5)
if (err != NET_SOCK_ERR_NONE) {
return (DEF_FALSE);
}
return (DEF_TRUE);
}Open a datagram socket (UDP protocol).
Convert an IPv4 address from ASCII dotted-decimal notation to a network protocol IPv4 address in host-order.
Populate the
NET_SOCK_ADDR_IPstructure for the server address and port, and convert it to network order.Transmit data to host
DATAGRAM_SERVER_IP_ADDRon portDATAGRAM_SERVER_PORT.Close the socket.