...
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
Panel |
---|
title | Figure - µC/TCP-IP Socket calls used in a typical TCP client-server application |
---|
|
Image Added |
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.
Code Block |
---|
language | cpp |
---|
firstline | 1 |
---|
title | Listing - Stream Server |
---|
linenumbers | true |
---|
|
#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);
} |
Panel |
---|
|
- Open a stream socket (TCP protocol).
- Populate the
NET_SOCK_ADDR_IP structure 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, and OSTaskCreate() 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.
Code Block |
---|
language | cpp |
---|
theme | Confluence |
---|
firstline | 1 |
---|
title | Listing - Stream Client |
---|
linenumbers | true |
---|
|
#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);
} |
Panel |
---|
|
- 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_IP structure 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:
...