Collaboration diagram for TCP Sockets:
![]() |
TCP clients typically use this order of API calls
This is quite similar to the traditional Berkley TCP Socket API used on desktop PCs.
The order of API calls for TCP servers is
Note, that this differs slightly from the Berkley API, where the initial socket is bound to a port and an additional socket is created when a connection is accepted. Nut/Net doesn't provide a bind call.
Most Nut/OS applications make use of the ability to assign a TCP socket to a stream and replace the somewhat primitive functions NutTcpSend() and NutTcpReceive() with stdio calls like fprintf() or fscanf().
#include <stdio.h> #include <sys/socket.h> ... TCPSOCKET *sock; FILE *stream; ... stream = _fdopen((int) sock, "r+b"); fprintf(stream, "Hello peer\r\n");
Remember, that Nut/OS streams are opened in text mode by default. Thus, we explicitly specify binary mode for the stream.
The application programmer can modify some default values of the TCP stack by calling NutTcpSetSockOpt(). This could be useful to fine tune the stack for maximum performance at minimum resource usage.
In addition you may call NutTcpSetSockOpt() to set a receive timeout in order to detect broken connections. That's often required, because TCP relies on a gracefully closed connection on the remote side. If the remote crashes or if the physical connection breaks, then NutTcpReceive() will never return unless a receive timeout value had been set. At least this is true for Nut/Net, which currently doesn't support the SO_KEEPALIVE option.
#include <sys/socket.h> ... UDPSOCKET *sock; u_long tmo = 3000; int rc; char buff[128]; ... NutTcpSetSockOpt(sock, SO_RCVTIMEO, &tmo, sizeof(tmo)); ... rc = NutTcpReceive(sock, buff, sizeof(buf)); if (rc == 0) { /* * A timeout occured. We will now perform an application specific * action to check wether our remote is still alive. */ ... }
Note again the difference to the Berkley API, where select() is used to determine receive timeouts.
Most socket API calls return -1 in case of a failure. The function NutTcpError() can be used to query a more specific error code.
#include <stdio.h> #include <sys/socket.h> ... TCPSOCKET *sock; u_long ip = inet_addr("192.168.1.100"); u_short port = 20191; int tcperr; ... if (NutTcpConnect(sock, ip, port)) { tcperr = NutTcpError(sock); printf("TCP Error: "); switch(tcperr) { case EHOSTUNREACH: printf("No route to %s\n", inet_ntoa(ip)); break; default: printf("%d\n", tcperr); break; } }
Data Structures | |
struct | tcp_socket |
TCP socket information structure. More... | |
Defines | |
#define | SO_FIN 0x01 |
Socket transmit flag. Send FIN after all data has been transmitted. | |
#define | SO_SYN 0x02 |
Socket transmit flag. Send SYN first. | |
#define | SO_FORCE 0x08 |
Socket transmit flag. Force sending ACK. | |
#define | SO_ACK 0x10 |
Socket transmit flag. Send ACK. | |
Typedefs | |
typedef tcp_socket | TCPSOCKET |
TCP socket type. | |
Functions | |
void | NutTcpDiscardBuffers (TCPSOCKET *sock) |
void | NutTcpDestroySocket (TCPSOCKET *sock) |
Destroy a previously allocated socket. | |
TCPSOCKET * | NutTcpFindSocket (u_short lport, u_short rport, u_long raddr) |
Find a matching socket. | |
TCPSOCKET * | NutTcpCreateSocket (void) |
Create a TCP socket. | |
int | NutTcpSetSockOpt (TCPSOCKET *sock, int optname, CONST void *optval, int optlen) |
Set value of a TCP socket option. | |
int | NutTcpGetSockOpt (TCPSOCKET *sock, int optname, void *optval, int optlen) |
Get a TCP socket option value. | |
int | NutTcpConnect (TCPSOCKET *sock, u_long addr, u_short port) |
Connect to a remote socket. | |
int | NutTcpAccept (TCPSOCKET *sock, u_short port) |
Wait for incoming connect from a remote socket. | |
int | NutTcpSend (TCPSOCKET *sock, CONST void *data, u_short len) |
Send data on a connected TCP socket. | |
int | NutTcpReceive (TCPSOCKET *sock, void *data, u_short size) |
Receive data on a connected TCP socket. | |
int | NutTcpCloseSocket (TCPSOCKET *sock) |
Close TCP socket. | |
int | NutTcpError (TCPSOCKET *sock) |
Return specific code of the last error. | |
int | NutTcpDeviceRead (TCPSOCKET *sock, void *buffer, int size) |
Read from virtual socket device. | |
int | NutTcpDeviceWrite (TCPSOCKET *sock, CONST void *buf, int size) |
Write to a socket. | |
int | NutTcpDeviceWrite_P (TCPSOCKET *sock, PGM_P buffer, int size) |
Write to device. | |
int | NutTcpDeviceIOCtl (TCPSOCKET *sock, int cmd, void *param) |
Driver control function. | |
Variables | |
TCPSOCKET * | tcpSocketList = 0 |
#define SO_FIN 0x01 |
Socket transmit flag. Send FIN after all data has been transmitted.
Definition at line 242 of file sock_var.h.
Referenced by NutTcpOutput().
#define SO_SYN 0x02 |
Socket transmit flag. Send SYN first.
Definition at line 243 of file sock_var.h.
Referenced by NutTcpOutput().
#define SO_FORCE 0x08 |
Socket transmit flag. Force sending ACK.
Definition at line 244 of file sock_var.h.
Referenced by NutTcpOutput(), NutTcpSm(), and NutTcpStateWindowEvent().
#define SO_ACK 0x10 |
Socket transmit flag. Send ACK.
Definition at line 245 of file sock_var.h.
Referenced by NutTcpOutput(), NutTcpSm(), and NutTcpStateWindowEvent().
typedef struct tcp_socket TCPSOCKET |
void NutTcpDiscardBuffers | ( | TCPSOCKET * | sock | ) |
Definition at line 217 of file tcpsock.c.
References _NETBUF::nb_next, NutNetBufFree(), tcp_socket::so_rx_buf, tcp_socket::so_rx_nbq, and tcp_socket::so_tx_nbq.
Referenced by NutTcpAbortSocket(), and NutTcpDestroySocket().
void NutTcpDestroySocket | ( | TCPSOCKET * | sock | ) |
Destroy a previously allocated socket.
Remove socket from the socket list and release occupied memory.
Applications must not call this function. It is automatically called by a timer after the socket has been closed by NutTcpCloseSocket().
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). |
Definition at line 246 of file tcpsock.c.
References memset(), NutHeapFree(), NutTcpDiscardBuffers(), tcp_socket::so_next, and tcpSocketList.
Referenced by NutTcpSm(), and NutTcpStateCloseEvent().
Find a matching socket.
Loop through all sockets and find a matching connection (prefered) or a listening socket.
Applications typically do not call this function.
lport | Local port number. | |
rport | Remote port number. | |
raddr | Remote IP address in network byte order. |
Definition at line 296 of file tcpsock.c.
References tcp_socket::so_local_port, tcp_socket::so_next, tcp_socket::so_remote_addr, tcp_socket::so_remote_port, tcp_socket::so_state, TCPS_CLOSED, and tcpSocketList.
TCPSOCKET* NutTcpCreateSocket | ( | void | ) |
Create a TCP socket.
Allocates a TCPSOCKET structure from heap memory, initializes it and returns a pointer to that structure.
The very first call will also start the TCP state machine, which is running in a separate thread.
Definition at line 348 of file tcpsock.c.
References IFTYP_TCPSOCK, NutGetTickCount(), NutHeapAllocClear(), NutTcpDeviceIOCtl(), NutTcpDeviceRead(), NutTcpDeviceWrite(), NutTcpDeviceWrite_P(), NutTcpInitStateMachine(), tcp_socket::so_devioctl, tcp_socket::so_devobsz, tcp_socket::so_devread, tcp_socket::so_devtype, tcp_socket::so_devwrite, tcp_socket::so_devwrite_P, tcp_socket::so_mss, tcp_socket::so_next, tcp_socket::so_rtto, tcp_socket::so_rx_bsz, tcp_socket::so_rx_win, tcp_socket::so_state, tcp_socket::so_tx_isn, tcp_socket::so_tx_nxt, tcp_socket::so_tx_una, TCP_MSS, TCP_WINSIZE, TCPS_CLOSED, and tcpSocketList.
Referenced by FtpService(), main(), NutFtpDataConnect(), Scanner(), Service(), and service().
int NutTcpSetSockOpt | ( | TCPSOCKET * | sock, | |
int | optname, | |||
CONST void * | optval, | |||
int | optlen | |||
) |
Set value of a TCP socket option.
The following values can be set:
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). | |
optname | Option to set. | |
optval | Pointer to the value. | |
optlen | Length of the value. |
Definition at line 405 of file tcpsock.c.
References EINVAL, EISCONN, tcp_socket::so_last_error, tcp_socket::so_mss, SO_RCVBUF, SO_RCVTIMEO, tcp_socket::so_read_to, tcp_socket::so_rx_bsz, tcp_socket::so_rx_win, SO_SNDTIMEO, tcp_socket::so_state, tcp_socket::so_write_to, TCP_MAXSEG, and TCPS_CLOSED.
Referenced by FtpService(), NutFtpDataConnect(), and Scanner().
int NutTcpGetSockOpt | ( | TCPSOCKET * | sock, | |
int | optname, | |||
void * | optval, | |||
int | optlen | |||
) |
Get a TCP socket option value.
The following values can be set:
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). | |
optname | Option to get. | |
optval | Points to a buffer receiving the value. | |
optlen | Length of the value buffer. |
Definition at line 488 of file tcpsock.c.
References EINVAL, tcp_socket::so_last_error, tcp_socket::so_mss, SO_RCVBUF, SO_RCVTIMEO, tcp_socket::so_read_to, tcp_socket::so_rx_bsz, SO_SNDTIMEO, tcp_socket::so_write_to, and TCP_MAXSEG.
Connect to a remote socket.
This function tries to establish a connection to the specified remote port of the specified remote server. The calling thread will be suspended until a connection is successfully established or an error occurs.
This function is typically used by TCP client applications.
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). | |
addr | IP address of the host to connect (network byte order). | |
port | Port number to connect (host byte order). |
Definition at line 565 of file tcpsock.c.
References _NUTDEVICE::dev_icb, EHOSTUNREACH, EISCONN, EOPNOTSUPP, htons, ifnet::if_local_ip, NutIpRouteQuery(), NutTcpStateActiveOpenEvent(), tcp_socket::so_last_error, tcp_socket::so_local_addr, tcp_socket::so_local_port, tcp_socket::so_next, tcp_socket::so_remote_addr, tcp_socket::so_remote_port, tcp_socket::so_state, TCPS_CLOSED, TCPS_LISTEN, and tcpSocketList.
Referenced by main(), NutFtpDataConnect(), and Scanner().
Wait for incoming connect from a remote socket.
The calling thread will be suspended until until an incoming connection request is received.
This function is typically used by TCP server applications.
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). | |
port | Port number to listen to (host byte order). |
Definition at line 641 of file tcpsock.c.
References htons, NutTcpStatePassiveOpenEvent(), and tcp_socket::so_local_port.
Referenced by FtpService(), main(), NutFtpDataConnect(), Service(), and service().
Send data on a connected TCP socket.
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). In addition a connection must have been established by calling NutTcpConnect or NutTcpAccept. | |
data | Pointer to a buffer containing the data to send. | |
len | Number of bytes to be sent. |
Definition at line 664 of file tcpsock.c.
References ENOTCONN, NutThreadYield(), tcp_socket::so_last_error, tcp_socket::so_mss, tcp_socket::so_state, tcp_socket::so_tx_nxt, tcp_socket::so_tx_una, and TCPS_ESTABLISHED.
Referenced by main(), and NutFtpTransferFile().
Receive data on a connected TCP socket.
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). In addition a connection must have been established by calling NutTcpConnect or NutTcpAccept. | |
data | Pointer to the buffer that receives the data. | |
size | Size of the buffer. |
Definition at line 734 of file tcpsock.c.
References ENOTCONN, memcpy(), _NETBUF::nb_ap, _NETBUF::nb_next, NutEventWait(), NutNetBufFree(), NutTcpStateWindowEvent(), NutThreadYield(), tcp_socket::so_last_error, tcp_socket::so_mss, tcp_socket::so_rd_cnt, tcp_socket::so_read_to, tcp_socket::so_rx_bsz, tcp_socket::so_rx_buf, tcp_socket::so_rx_cnt, tcp_socket::so_rx_tq, tcp_socket::so_rx_win, tcp_socket::so_state, _NBDATA::sz, TCPS_CLOSE_WAIT, TCPS_ESTABLISHED, and _NBDATA::vp.
Referenced by main(), NutFtpTransferFile(), and NutTcpDeviceRead().
int NutTcpCloseSocket | ( | TCPSOCKET * | sock | ) |
Close TCP socket.
Note, that the socket may not be immediately destroyed after calling this function. However, the application must not use the socket after this call.
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). |
Definition at line 826 of file tcpsock.c.
References NutTcpDeviceWrite(), and NutTcpStateCloseEvent().
Referenced by FtpService(), main(), NutFtpDataConnect(), NutFtpTransferDirectory(), NutFtpTransferFile(), Scanner(), Service(), and service().
int NutTcpError | ( | TCPSOCKET * | sock | ) |
Return specific code of the last error.
Possible error codes (net/errno.h) are:
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). |
Definition at line 882 of file tcpsock.c.
References ENOTSOCK, and tcp_socket::so_last_error.
Referenced by Scanner().
int NutTcpDeviceRead | ( | TCPSOCKET * | sock, | |
void * | buffer, | |||
int | size | |||
) |
Read from virtual socket device.
TCP sockets can be used like other Nut/OS devices. This routine is part of the virtual socket device driver.
This function is called by the low level input routines of the C runtime library, using the _NUTDEVICE::dev_read entry.
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). | |
buffer | Pointer to the buffer that receives the data. | |
size | Maximum number of bytes to read. |
Definition at line 908 of file tcpsock.c.
References NutTcpReceive().
Referenced by NutTcpCreateSocket().
int NutTcpDeviceWrite | ( | TCPSOCKET * | sock, | |
CONST void * | buf, | |||
int | size | |||
) |
Write to a socket.
TCP sockets can be used like other Nut/OS devices. This routine is part of the virtual socket device driver.
This function is called by the low level output routines of the C runtime library, using the _NUTDEVICE::dev_write entry.
In contrast to NutTcpSend() this routine provides some buffering.
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). | |
buf | Pointer to the data to be written. | |
size | Number of bytes to write. If zero, then the output buffer will be flushed. |
Definition at line 948 of file tcpsock.c.
References ENOTCONN, memcpy(), NutHeapAlloc(), NutHeapFree(), tcp_socket::so_devobsz, tcp_socket::so_devobuf, tcp_socket::so_devocnt, tcp_socket::so_last_error, tcp_socket::so_state, and TCPS_ESTABLISHED.
Referenced by NutTcpCloseSocket(), NutTcpCreateSocket(), and NutTcpDeviceWrite_P().
int NutTcpDeviceWrite_P | ( | TCPSOCKET * | sock, | |
PGM_P | buffer, | |||
int | size | |||
) |
Write to device.
This function is implemented for CPUs with Harvard Architecture only.
TCP sockets can be used like other Nut/OS devices. This routine is part of the virtual socket device driver and similar to NutTcpDeviceWrite() except that the data is located in program memory.
This function is called by the low level output routines of the C runtime library, using the _NUTDEVICE::dev_write_P entry.
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). | |
buffer | Pointer to the data in program space to be written. | |
size | Number of bytes to write. |
Definition at line 1076 of file tcpsock.c.
References memcpy_P, NutHeapAlloc(), NutHeapFree(), and NutTcpDeviceWrite().
Referenced by NutTcpCreateSocket().
int NutTcpDeviceIOCtl | ( | TCPSOCKET * | sock, | |
int | cmd, | |||
void * | param | |||
) |
Driver control function.
Used by the virtual device driver to modify or query device specific settings.
sock | Socket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). | |
cmd | Requested control function. May be set to one of the following constants: | |
param | Points to a buffer that contains any data required for the given control function or receives data from that function. |
Definition at line 1114 of file tcpsock.c.
References IOCTL_GETFILESIZE, IOCTL_GETINBUFCOUNT, IOCTL_GETOUTBUFCOUNT, tcp_socket::so_devocnt, tcp_socket::so_rd_cnt, and tcp_socket::so_rx_cnt.
Referenced by NutTcpCreateSocket().
TCPSOCKET* tcpSocketList = 0 |