Stream Socket (TCP)
The figure below uses the Micrium proprietary socket API function calls. A similar example could be written using the BSD socket API.
Typically, after a TCP server starts, TCP clients can connect and send requests to the server. A TCP server waits until client connections arrive and then creates a dedicated TCP socket connection to process the client’s requests and reply back to the client (if necessary). This continues until either the client or the server closes the dedicated client-server connection. Also while handling multiple, simultaneous client-server connections, the TCP server can wait for new client-server connections
Stream Server (TCP Server)
This example presents a very basic client-server application over a TCP connection. The server presented is simply waits for a connection and send the string ‘Hello World!’. See TCPIP API Reference Core for a list of all µC/TCP-IP socket API functions.
Listing - Stream Server
#define TCP_SERVER_PORT 10000
#define TCP_SERVER_CONN_Q_SIZE 1
#define TCP_SERVER_TX_STR "Hello World!"
CPU_BOOLEAN TestTCPServer (void)
{
NET_SOCK_ID sock_listen;
NET_SOCK_ID sock_req;
NET_SOCK_ADDR_IP server_sock_addr_ip;
NET_SOCK_ADDR_LEN server_sock_addr_ip_size;
NET_SOCK_ADDR_IP client_sock_addr_ip;
NET_SOCK_ADDR_LEN client_sock_addr_ip_size;
CPU_BOOLEAN attempt_conn;
CPU_CHAR *pbuf;
CPU_INT16S buf_len;
NET_SOCK_RTN_CODE tx_size;
NET_ERR err;
pbuf = TCP_SERVER_TX_STR;
buf_len = Str_Len(TCP_SERVER_TX_STR);
sock_listen = NetSock_Open( NET_SOCK_ADDR_FAMILY_IP_V4, (1)
NET_SOCK_TYPE_STREAM,
NET_SOCK_PROTOCOL_TCP,
&err);
if (err != NET_SOCK_ERR_NONE) {
return (DEF_FALSE);
}
server_sock_addr_ip_size = sizeof(server_sock_addr_ip); (2)
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(NET_SOCK_ADDR_IP_WILD_CARD);
server_sock_addr_ip.Port = NET_UTIL_HOST_TO_NET_16(TCP_SERVER_PORT);
NetSock_Bind((NET_SOCK_ID ) sock_listen, (3)
(NET_SOCK_ADDR *)&server_sock_addr_ip,
(NET_SOCK_ADDR_LEN) NET_SOCK_ADDR_SIZE,
(NET_ERR *)&err);
if (err != NET_SOCK_ERR_NONE) {
NetSock_Close(sock_listen, &err);
return (DEF_FALSE);
}
NetSock_Listen( sock_listen, (4)
TCP_SERVER_CONN_Q_SIZE,
&err);
if (err != NET_SOCK_ERR_NONE) {
NetSock_Close(sock_listen, &err);
return (DEF_FALSE);
}
do {
client_sock_addr_ip_size = sizeof(client_sock_addr_ip);
sock_req = NetSock_Accept((NET_SOCK_ID ) sock_listen, (5)
(NET_SOCK_ADDR *)&client_sock_addr_ip,
(NET_SOCK_ADDR_LEN *)&client_sock_addr_ip_size,
(NET_ERR *)&err);
switch (err) {
case NET_SOCK_ERR_NONE:
attempt_conn = DEF_NO;
break;
case NET_ERR_INIT_INCOMPLETE:
case NET_SOCK_ERR_NULL_PTR:
case NET_SOCK_ERR_NONE_AVAIL:
case NET_SOCK_ERR_CONN_ACCEPT_Q_NONE_AVAIL:
case NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT:
case NET_OS_ERR_LOCK:
attempt_conn = DEF_YES;
break;
default:
attempt_conn = DEF_NO;
break;
}
} while (attempt_conn == DEF_YES);
if (err != NET_SOCK_ERR_NONE) {
NetSock_Close(sock_req, &err);
return (DEF_FALSE);
}
tx_size = NetSock_TxData( sock_req, (6)
pbuf,
buf_len,
NET_SOCK_FLAG_NONE,
&err);
NetSock_Close(sock_req, &err); (7)
NetSock_Close(sock_listen, &err);
return (DEF_TRUE);
}Open a stream socket (TCP 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.Set the socket to listen for a connection request coming on the specified port.
Accept the incoming connection request, and return a new socket for this particular connection. Note that this function call is being called from inside a loop because it might timeout (no client attempts to connect to the server).
One the connection has been established between the server and a client, transmit the message. Note that the return value of this function is not used here, but a real application should make sure all the message has been sent by comparing that value with the length of the message.
Close both listen and request sockets. When the server need to stay active, the listen socket stays open so that I can accept additional connection requests. Usually, the server will wait for a connection,
accept()it, andOSTaskCreate()a task to handle it.
Stream Client (TCP Client)
The client of the listing below connects to the specified server and receives the string the server sends.
Listing - Stream Client
#define TCP_SERVER_IP_ADDR "192.168.1.101"
#define TCP_SERVER_PORT 10000
#define RX_BUF_SIZE 15
CPU_BOOLEAN TestTCPClient (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;
NET_SOCK_RTN_CODE conn_rtn_code;
NET_SOCK_RTN_CODE rx_size;
CPU_CHAR rx_buf[RX_BUF_SIZE];
NET_ERR err;
sock = NetSock_Open( NET_SOCK_ADDR_FAMILY_IP_V4, (1)
NET_SOCK_TYPE_STREAM,
NET_SOCK_PROTOCOL_TCP,
&err);
if (err != NET_SOCK_ERR_NONE) {
return (DEF_FALSE);
}
server_ip_addr = NetASCII_Str_to_IP(TCP_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(TCP_SERVER_PORT);
conn_rtn_code = NetSock_Conn((NET_SOCK_ID ) sock, (4)
(NET_SOCK_ADDR *)&server_sock_addr_ip,
(NET_SOCK_ADDR_LEN) sizeof(server_sock_addr_ip),
(NET_ERR *)&err);
if (err != NET_SOCK_ERR_NONE) {
NetSock_Close(sock, &err);
return (DEF_FALSE);
}
rx_size = NetSock_RxData( sock, (5)
rx_buf,
RX_BUF_SIZE,
NET_SOCK_FLAG_NONE,
&err);
if (err != NET_SOCK_ERR_NONE) {
NetSock_Close(sock, &err);
return (DEF_FALSE);
}
NetSock_Close(sock, &err); (6)
return (DEF_TRUE);
}Open a stream socket (TCP 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.Connect the socket to a remote host.
Receive data from the connected socket. Note that the return value for this function is not used here.However, a real application should make sure everything has been received.
Close the socket.
TCP Connection Configuration
µC/TCP-IP provides a set of APIs to configure TCP connections on an individual basis. These APIs are listed below and detailed in TCP Functions: