Socket Programming
The following sections provide sample code describing how sockets work.
For those interested in BSD socket programming, there are plenty of books, online references, and articles dedicated to this subject.
The sockets API provides many configuration option, it's very difficult to cover all variations of its use. The examples have been designed to be as simple as possible. Hence, only basic error checking is performed. When it comes to building real applications, those checks should be extended to deliver a product that is as robust as possible.
Socket Description
A network socket is an inter-process communication implementation using an IP stack on a network. Sockets allow one application process to communicate with another whether it is local on the same system or remote over the network. You use and control a socket using an application programming interface (API) provided by the Network stack and which is usually based on Berkeley sockets standard.
Two socket types are identified: Datagram sockets and Stream sockets and using the following standard protocol:
Protocol | Description |
---|---|
IP | Internet Protocol provides network routing using IPv4 or IPv6 addressing. |
UDP | User Datagram Protocol - Datagram sockets (Connectionless sockets) |
TCP | Transmission Control Protocol - Stream sockets (Connection-oriented sockets) |
Configuration
Some parameters should be configured and/or optimized for your project requirements. Please refer to the section Socket Layer Configuration for further details.
Using Network Socket Programming API
Wherever you want to configure, access or use a socket you should include one or many of these files:
Include file | Description |
---|---|
Source/net_app.h | Functions used for NetApp API |
Source/net_sock.h | Functions used for NetSock API |
Source/net_bsd.h | Functions used for BSD API |
Source/net_tcp.h | Functions used for Stream Socket Option API |
Source/net_util.h | Functions and Macro used for conversion utilities API |
Source/net_ascii.h | Functions and Macro used for conversion utilities API |
IP/IPv4/net_ipv4.h | Functions used for IPv4 options API |
IP/IPv6/net_ipv6.h | Functions used for IPv6 options API |
API Reference
In addition to the BSD 4.x sockets application interface (API), the µC/TCP-IP stack gives the developer the opportunity to use Micrium’s own socket functions with which to interact.
Although there is a great deal of similarity between the two APIs, the parameters of the two sets of functions differ slightly. The purpose of the following sections is o give developers a first look at Micrium’s functions by providing concrete examples of how to use the API.
- BSD APIs are following BSD 4.x functions prototype and there are presented in the section BSD Functions.
- Net Sock APIs are the low level socket API. They are based on BSD sockets but with more arguments and it can return the error cause. Net Sock APIs are presented in the section Network Socket Functions.
- Net APP APIs include more parameters of the Net Sock API, to accomplish some operation that should be always performed when calling Socket API, such as setting timeout, retry, apply delay and such. Basically this is a wrapper of Net Sock APIs. Net APP APIs are presented in the section Network Application Interface Functions.
Functions
The following functions must be used to open, connect, receive, transmit, close and so on:
BSD | Net Sock | Net App | Description |
---|---|---|---|
socket() | NetSock_Open() | NetApp_SockOpen() | Create a datagram (i.e., UDP) or stream (i.e., TCP) type socket. |
bind() | NetSock_Bind() | NetApp_SockBind() | Assign network addresses to sockets. |
connect() | NetSock_Conn() | NetApp_SockConn() | Connect a local socket to a remote socket address. |
listen() | NetSock_Listen() | NetApp_SockListen() | Set a socket to accept incoming connections. |
accept() | NetSock_Accept() | NetApp_SockAccept() | Wait for new socket connections on a listening server socket. |
recv() / recvfrom() | NetSock_RxData() / NetSock_RxDataFrom() | NetApp_SockRx() | Copy up to a specified number of bytes received from a remote socket into an application memory buffer. |
send() / sendto() | NetSock_TxData() / NetSock_TxDataTo() | NetApp_SockTx() | Copy bytes from an application memory buffer into a socket to send to a remote socket. |
close() | NetSock_Close() | NetApp_SockClose() | Terminate communication and free a socket. |
select() | NetSock_Sel() | N/A | Check if any sockets are ready for available read or write operations or error conditions. |
N/A | NetSock_SelAbort() | N/A | Abort a select (i.e. unblock task(s) waiting on socket(s) using the select) |
Conversion Utilities
The following functions should be used when converting 16 or 32 bit values from or to network order or even when converting IP address.
BSD | µC/TCPIP Functions | Description |
---|---|---|
htonl | Convert 32-bit integer values from network-order to CPU host-order. | |
htons() | NET_UTIL_HOST_TO_NET_16() | Convert 16-bit integer values from network-order to CPU host-order. |
ntohl() | NET_UTIL_NET_TO_HOST_32() | Convert 32-bit integer values from network-order to CPU host-order. |
ntohs() | NET_UTIL_NET_TO_HOST_16() | Convert 16-bit integer values from network-order to CPU host-order. |
inet_addr() | NetASCII_Str_to_IPv4() | Convert a string of an IPv4 address in dotted-decimal notation to an IPv4 address in host-order. |
inet_aton() | NetASCII_Str_to_IPv4() | Convert an IPv4 address in ASCII dotted-decimal notation to a network protocol IPv4 address in network-order. |
inet_ntoa() | NetASCII_IPv4_to_Str() | Convert an IPv4 address in host-order into an IPv4 dotted-decimal notation ASCII string. |
Socket option function
It is possible to configure many options on a socket, with the followings function you could configure majority of socket's option but some other option can be accessed using some specific API, please refer to Socket Options section.
BSD | Net Sock | Description |
---|---|---|
getsockopt() | NetSock_OptGet() | Get a specific option value on a specific socket. |
setsockopt() | NetSock_OptSet() | Set a specific option value on a specific socket. |
Select() Macro
The following functions should be used when select() is used. It helps to configure and read descriptors to a select() calls.
BSD | Net Sock | Description |
---|---|---|
FD_CLR() | NET_SOCK_DESC_CLR() | Remove a socket file descriptor ID as a member of a file descriptor set. |
FD_ISSET() | NET_SOCK_DESC_IS_SET() | Check if a socket file descriptor ID is a member of a file descriptor set. |
FD_SET() | NET_SOCK_DESC_SET() | Add a socket file descriptor ID as a member of a file descriptor set. |
FD_ZERO() | NET_SOCK_DESC_INIT() | Initialize/zero-clear a file descriptor set. |
Miscellaneous
Here is a list of other APIs functions that can help in certain condition:
Function | Description |
---|---|
NetApp_SetSockAddr() | Setup a socket address from an IPv4 or an IPv6 address. |
NetApp_ClientStreamOpen() | Open a stream socket for a client using an IPv4 or IPv6 address. |
NetApp_ClientStreamOpenByHostname() | Open a stream socket for a client using a hostname (resolve the hostname using µC/DNSc + Autoselect remote address) |
NetApp_TimeDly_ms() | Delay for specified time, in milliseconds. |
NetSock_GetConnTransportID() | Gets a socket’s transport layer connection handle ID (e.g., TCP connection ID) if available. |
NetSock_IsConn() | Check if a socket is connected to a remote socket. |
NetSock_PoolStatResetMaxUsed() | Reset Network Sockets’ statistics pool’s maximum number of entries used. |
Socket Error Codes
When socket functions return error codes, the error codes should be inspected to determine if the error is a temporary, non-fault condition (such as no data to receive) or fatal (such as the socket has been closed).
Fatal Socket Error Codes
Whenever any of the following fatal error codes are returned by any µC/TCP-IP socket function, that socket must be immediately closed()
’d without further access by any other socket functions:
NET_SOCK_ERR_INVALID_FAMILY
NET_SOCK_ERR_INVALID_PROTOCOL
NET_SOCK_ERR_INVALID_TYPE
NET_SOCK_ERR_INVALID_STATE
NET_SOCK_ERR_FAULT
Whenever any of the following fatal error codes are returned by any µC/TCP-IP socket function, that socket must not be accessed by any other socket functions but must also not be closed()
’d:
NET_SOCK_ERR_NOT_USED
Socket Error Code List
All the possible error codes returned by the µC/TCP-IP stack are defined in net_err.h
. Please refer to net_err.h
for more details on any specific error code.