Nut/OS  4.10.3
API Reference
TCP Sockets

Application interface for TCP sockets. More...

Collaboration diagram for TCP Sockets:

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 struct tcp_socket TCPSOCKET
 TCP socket type.

Functions

void NutTcpDiscardBuffers (TCPSOCKET *sock)
void NutTcpDestroySocket (TCPSOCKET *sock)
 Destroy a previously allocated socket.
TCPSOCKETNutTcpFindSocket (uint16_t lport, uint16_t rport, uint32_t raddr)
 Find a matching socket.
TCPSOCKETNutTcpCreateSocket (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, uint32_t addr, uint16_t port)
 Connect to a remote socket.
int NutTcpAccept (TCPSOCKET *sock, uint16_t port)
 Wait for incoming connect from a remote socket.
int NutTcpSend (TCPSOCKET *sock, CONST void *data, int len)
 Send data on a connected TCP socket.
int NutTcpReceive (TCPSOCKET *sock, void *data, int 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

TCPSOCKETtcpSocketList = 0

Detailed Description

Application interface 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;
     }
 }

Define Documentation

#define SO_FIN   0x01

Socket transmit flag. Send FIN after all data has been transmitted.

Definition at line 270 of file sock_var.h.

Referenced by NutTcpOutput().

#define SO_SYN   0x02

Socket transmit flag. Send SYN first.

Definition at line 271 of file sock_var.h.

Referenced by NutTcpOutput().

#define SO_FORCE   0x08

Socket transmit flag. Force sending ACK.

Definition at line 272 of file sock_var.h.

Referenced by NutTcpOutput(), NutTcpSm(), and NutTcpStateWindowEvent().

#define SO_ACK   0x10

Socket transmit flag. Send ACK.

Definition at line 273 of file sock_var.h.

Referenced by NutTcpOutput(), NutTcpSend(), NutTcpSm(), and NutTcpStateWindowEvent().


Typedef Documentation

typedef struct tcp_socket TCPSOCKET

TCP socket type.

Definition at line 200 of file sock_var.h.


Function Documentation

void NutTcpDiscardBuffers ( TCPSOCKET sock)

Definition at line 244 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().

Here is the call graph for this function:

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().

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().

Definition at line 273 of file tcpsock.c.

References free(), memset(), NutTcpDiscardBuffers(), tcp_socket::so_devobuf, tcp_socket::so_devocnt, tcp_socket::so_next, and tcpSocketList.

Referenced by NutTcpSm(), and NutTcpStateCloseEvent().

Here is the call graph for this function:

TCPSOCKET* NutTcpFindSocket ( uint16_t  lport,
uint16_t  rport,
uint32_t  raddr 
)

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.

Parameters:
lportLocal port number.
rportRemote port number.
raddrRemote IP address in network byte order.
Returns:
Socket descriptor.

Definition at line 323 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 TCPS_LISTEN.

Referenced by NutTcpSm().

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.

Returns:
Socket descriptor of the newly created TCP socket or 0 if there is not enough memory left.

Definition at line 373 of file tcpsock.c.

References calloc, IFTYP_TCPSOCK, IPPROTO_TCP, NutGetTickCount(), NutRegisterIpHandler(), NutTcpDeviceIOCtl(), NutTcpDeviceRead(), NutTcpDeviceWrite(), NutTcpDeviceWrite_P(), NutTcpInitStateMachine(), NutTcpInput(), 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 main(), NutFtpDataConnect(), NutSmtpConnect(), service(), and Service().

Here is the call graph for this function:

int NutTcpSetSockOpt ( TCPSOCKET sock,
int  optname,
CONST void *  optval,
int  optlen 
)

Set value of a TCP socket option.

The following values can be set:

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().
optnameOption to set.
optvalPointer to the value.
optlenLength of the value.
Returns:
0 on success, -1 otherwise. The specific error code can be retrieved by calling NutTcpError().

Definition at line 433 of file tcpsock.c.

References EINVAL, EISCONN, tcp_socket::so_last_error, tcp_socket::so_mss, SO_RCVBUF, 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 NutFtpDataConnect(), and NutSmtpConnect().

int NutTcpGetSockOpt ( TCPSOCKET sock,
int  optname,
void *  optval,
int  optlen 
)

Get a TCP socket option value.

The following values can be set:

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().
optnameOption to get.
optvalPoints to a buffer receiving the value.
optlenLength of the value buffer.
Returns:
0 on success, -1 otherwise. The specific error code can be retrieved by calling NutTcpError().

Definition at line 516 of file tcpsock.c.

References EINVAL, tcp_socket::so_last_error, tcp_socket::so_mss, SO_RCVBUF, tcp_socket::so_rx_bsz, SO_SNDTIMEO, tcp_socket::so_write_to, and TCP_MAXSEG.

int NutTcpConnect ( TCPSOCKET sock,
uint32_t  addr,
uint16_t  port 
)

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.

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().
addrIP address of the host to connect (network byte order).
portPort number to connect (host byte order).
Returns:
0 on success, -1 otherwise. The specific error code can be retrieved by calling NutTcpError().

Definition at line 593 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 NutSmtpConnect().

Here is the call graph for this function:

int NutTcpAccept ( TCPSOCKET sock,
uint16_t  port 
)

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.

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().
portPort number to listen to (host byte order).
Returns:
0 on success, -1 otherwise. The specific error code can be retrieved by calling NutTcpError().

Definition at line 669 of file tcpsock.c.

References htons, NutTcpStatePassiveOpenEvent(), and tcp_socket::so_local_port.

Referenced by main(), NutFtpDataConnect(), service(), and Service().

Here is the call graph for this function:

int NutTcpSend ( TCPSOCKET sock,
CONST void *  data,
int  len 
)

Send data on a connected TCP socket.

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). In addition a connection must have been established by calling NutTcpConnect or NutTcpAccept.
dataPointer to a buffer containing the data to send.
lenNumber of bytes to be sent.
Returns:
If successful, the number of bytes added to the socket transmit buffer. This is limited to the maximum segment size of the connection and thus may be less than the specified number of bytes to send. The return value -1 indicates a fatal error. On time out, a value of 0 is returned.

Definition at line 692 of file tcpsock.c.

References ENOTCONN, NutEventWait(), NutTcpOutput(), NutThreadYield(), SO_ACK, tcp_socket::so_last_error, tcp_socket::so_mss, tcp_socket::so_state, tcp_socket::so_tx_flags, tcp_socket::so_tx_nxt, tcp_socket::so_tx_tq, tcp_socket::so_tx_una, tcp_socket::so_write_to, and TCPS_ESTABLISHED.

Referenced by main(), and NutFtpTransferFile().

Here is the call graph for this function:

int NutTcpReceive ( TCPSOCKET sock,
void *  data,
int  size 
)

Receive data on a connected TCP socket.

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket(). In addition a connection must have been established by calling NutTcpConnect or NutTcpAccept.
dataPointer to the buffer that receives the data.
sizeSize of the buffer.
Returns:
If successful, the number of received data bytes is returned. This may be less than the specified size of the buffer. The return value 0 indicates a timeout, while -1 is returned in case of an error or broken connection. Call NutTcpError() to determine the specific error code.

Definition at line 762 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_apc, 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().

Here is the call graph for this function:

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.

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().
Returns:
0 on success, -1 otherwise.

Definition at line 855 of file tcpsock.c.

References NutTcpDeviceWrite(), and NutTcpStateCloseEvent().

Referenced by main(), NutFtpDataConnect(), NutFtpTransferDirectoryOptions(), NutFtpTransferFile(), NutSmtpDisconnect(), service(), and Service().

Here is the call graph for this function:

int NutTcpError ( TCPSOCKET sock)

Return specific code of the last error.

Possible error codes (net/errno.h) are:

  • EWOULDBLOCK: Operation would block
  • EINPROGRESS: Operation now in progress
  • EALREADY: Operation already in progress
  • ENOTSOCK: Socket operation on non-socket
  • EDESTADDRREQ: Destination address required
  • EMSGSIZE: Message too long
  • EPROTOTYPE: Protocol wrong type for socket
  • ENOPROTOOPT: Protocol not available
  • EPROTONOSUPPORT: Protocol not supported
  • ESOCKTNOSUPPORT: Socket type not supported
  • EOPNOTSUPP: Operation not supported on socket
  • EPFNOSUPPORT: Protocol family not supported
  • EAFNOSUPPORT: Address family not supported by protocol family
  • EADDRINUSE: Address already in use
  • EADDRNOTAVAIL: Can't assign requested address
  • ENETDOWN: Network is down
  • ENETUNREACH: Network is unreachable
  • ENETRESET: Network dropped connection on reset
  • ECONNABORTED: Software caused connection abort
  • ECONNRESET: Connection reset by peer
  • ENOBUFS: No buffer space available
  • EISCONN: Socket is already connected
  • ENOTCONN: Socket is not connected
  • ESHUTDOWN: Can't send after socket shutdown
  • ETOOMANYREFS: Too many references: can't splice
  • ETIMEDOUT: Connection timed out
  • ECONNREFUSED: Connection refused
  • ELOOP: Too many levels of symbolic links
  • ENAMETOOLONG: File name too long
  • EHOSTDOWN: Host is down
  • EHOSTUNREACH: No route to host
  • ENOTEMPTY: Directory not empty
Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().
Note:
Applications must not call this function to retrieve the error code if NutTcpCloseSocket() or NutTcpDestroySocket() failed.
Todo:
Not all error codes are properly set right now. Some socket functions return an error without setting an error code.

Definition at line 911 of file tcpsock.c.

References ENOTSOCK, and tcp_socket::so_last_error.

Referenced by NutFtpDataConnect().

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.

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().
bufferPointer to the buffer that receives the data.
sizeMaximum number of bytes to read.
Returns:
The number of bytes read, which may be less than the number of bytes specified. A return value of -1 indicates an error, while zero is returned in case of a timeout.

Definition at line 937 of file tcpsock.c.

References NutTcpReceive().

Referenced by NutTcpCreateSocket().

Here is the call graph for this function:

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.

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().
bufPointer to the data to be written.
sizeNumber of bytes to write. If zero, then the output buffer will be flushed.
Returns:
The number of bytes written. A return value of -1 indicates an error.

Definition at line 977 of file tcpsock.c.

References ENOTCONN, free(), malloc(), memcpy(), 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().

Here is the call graph for this function:

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.

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().
bufferPointer to the data in program space to be written.
sizeNumber of bytes to write.
Warning:
Inefficient implementation. No buffering has been implemented. Thus, each call will result in a separate TCP segment.

Definition at line 1105 of file tcpsock.c.

References memcpy_P, NutHeapAlloc, NutHeapFree, and NutTcpDeviceWrite().

Referenced by NutTcpCreateSocket().

Here is the call graph for this function:

int NutTcpDeviceIOCtl ( TCPSOCKET sock,
int  cmd,
void *  param 
)

Driver control function.

Used by the virtual device driver to modify or query device specific settings.

Parameters:
sockSocket descriptor. This pointer must have been retrieved by calling NutTcpCreateSocket().
cmdRequested control function. May be set to one of the following constants:
paramPoints to a buffer that contains any data required for the given control function or receives data from that function.
Returns:
0 on success, -1 otherwise.

Definition at line 1143 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().


Variable Documentation

Global linked list of all TCP sockets.

Definition at line 238 of file tcpsock.c.

Referenced by NutTcpConnect(), NutTcpCreateSocket(), and NutTcpDestroySocket().