5.9. socket — Internet communication

Sockets are used to communicate over IP networks. TCP and UDP are the most common transport protocols.

No more than one thread may read from a socket at any given moment. The same applies when writing to a socket. The reader and writer may be different threads, though. The behaviour is undefined if more threads use the same socket simultaneously. The application will likely crash. Add a semaphore to protect the socket if more threads need access to a socket.

Below is a TCP client example that connects to a server and sends data.

uint8_t buf[16];
struct socket_t tcp;
struct inet_addr_t local_addr, remote_addr;

/* Set the local and remote addresses. */
inet_aton("192.168.1.103", &local_addr.ip);
local_addr.port = 6000;
inet_aton("192.168.1.106", &remote_addr.ip);
remote_addr.port = 5000;

/* Initialize the socket and connect to the server. */
socket_open_tcp(&tcp);
socket_bind(&tcp, &local_addr);
socket_connect(&tcp, &remote_addr);

/* Send the data. */
memset(buf, 0, sizeof(buf));
socket_write(&tcp, buf, sizeof(buf));

/* Close the connection. */
socket_close(&tcp);

And below is the same scenario for UDP.

uint8_t buf[16];
struct socket_t udp;
struct socket_addr_t local_addr, remote_addr;

/* Set the local and remote addresses. */
inet_aton("192.168.1.103", &local_addr.ip);
local_addr.port = 6000;
inet_aton("192.168.1.106", &remote_addr.ip);
remote_addr.port = 5000;

/* Initialize the socket and connect to the server. */
socket_open_udp(&udp);
socket_bind(&udp, &local_addr);
socket_connect(&udp, &remote_addr);

/* Send the data. */
memset(buf, 0, sizeof(buf));
socket_send(&udp, buf, sizeof(buf));

/* Close the connection. */
socket_close(&udp);

Source code: src/inet/socket.h, src/inet/socket.c


Defines

SOCKET_DOMAIN_INET 0
SOCKET_TYPE_STREAM 1

TCP socket type.

SOCKET_TYPE_DGRAM 2

UDP socket type.

SOCKET_TYPE_RAW 3

RAW socket type.

SOCKET_PROTO_ICMP 0

Functions

int socket_module_init(void)

Initialize the socket module. This function will start the lwIP TCP/IP stack. This function must be called before calling any other function in this module.

The module will only be initialized once even if this function is called multiple times.

Return
zero(0) or negative error code.

int socket_open_tcp(struct socket_t *self_p)

Initialize given TCP socket.

Return
zero(0) or negative error code.
Parameters
  • self_p: Socket to initialize.

int socket_open_udp(struct socket_t *self_p)

Initialize given UDP socket.

Return
zero(0) or negative error code.
Parameters
  • self_p: Socket to initialize.

int socket_open_raw(struct socket_t *self_p)

Initialize given RAW socket.

Return
zero(0) or negative error code.
Parameters
  • self_p: Socket to initialize.

int socket_open(struct socket_t *self_p, int domain, int type, int protocol)

Initialize given socket.

Return
zero(0) or negative error code.
Parameters
  • self_p: Socket to initialize.
  • domain: Socket domain.
  • type: Socket type.
  • protocol: Socket protocol.

int socket_close(struct socket_t *self_p)

Close given socket. No data transfers are allowed on after the socket has been closed.

Return
zero(0) or negative error code.
Parameters
  • self_p: Socket to close.

int socket_bind(struct socket_t *self_p, const struct inet_addr_t *local_addr_p)

Bind given local address to given socket.

Return
zero(0) or negative error code.
Parameters
  • self_p: Socket.
  • local_addr_p: Local address.

int socket_listen(struct socket_t *self_p, int backlog)

Listen for connections from remote clients. Only applicable for TCP sockets.

Return
zero(0) or negative error code.
Parameters
  • self_p: Socket to listen on.
  • backlog: Unused.

int socket_connect(struct socket_t *self_p, const struct inet_addr_t *remote_addr_p)

Connect to given remote address. Connecting a UDP socket sets the default remote address for outgoing datagrams. For TCP a three-way handshake with the remote peer is initiated.

Return
zero(0) or negative error code.
Parameters
  • self_p: Socket.
  • remote_addr_p: Remote address.

int socket_connect_by_hostname(struct socket_t *self_p, const char *hostname_p, uint16_t port)

Connect to the remote device with given hostname.

In computer networking, a hostname (archaically nodename) is a label that is assigned to a device connected to a computer network and that is used to identify the device in various forms of electronic communication, such as the World Wide Web.

Return
zero(0) or negative error code.
Parameters
  • self_p: Socket.
  • hostname_p: The hostname of the remote device to connect to.
  • port: Remote device port to connect to.

int socket_accept(struct socket_t *self_p, struct socket_t *accepted_p, struct inet_addr_t *remote_addr_p)

Accept a client connect attempt. Only applicable for TCP sockets that are listening for connections.

Return
zero(0) or negative error code.
Parameters
  • self_p: TCP socket.
  • accepted_p: New client socket of the accepted client.
  • remote_addr_p: Address of the client.

ssize_t socket_sendto(struct socket_t *self_p, const void *buf_p, size_t size, int flags, const struct inet_addr_t *remote_addr_p)

Write data to given socket. Only used by UDP sockets.

Return
Number of sent bytes or negative error code.
Parameters
  • self_p: Socket to send data on.
  • buf_p: Buffer to send.
  • size: Size of buffer to send.
  • flags: Unused.
  • remote_addr_p: Remote address to send the data to.

ssize_t socket_recvfrom(struct socket_t *self_p, void *buf_p, size_t size, int flags, struct inet_addr_t *remote_addr_p)

Read data from given socket. Only used by UDP sockets.

Return
Number of received bytes or negative error code.
Parameters
  • self_p: Socket to receive data on.
  • buf_p: Buffer to read into.
  • size: Size of buffer to read.
  • flags: Unused.
  • remote_addr_p: Remote address to receive data from.

ssize_t socket_write(struct socket_t *self_p, const void *buf_p, size_t size)

Write data to given TCP or UDP socket. For UDP sockets, socket_connect() must have been called prior to calling this function.

Return
Number of written bytes or negative error code.
Parameters
  • self_p: Socket.
  • buf_p: Buffer to send.
  • size: Numer of bytes to send.

ssize_t socket_read(struct socket_t *self_p, void *buf_p, size_t size)

Read data from given socket.

Return
Number of read bytes or negative error code.
Parameters
  • self_p: Socket.
  • buf_p: Buffer to read into.
  • size: Number of bytes to read.

ssize_t socket_size(struct socket_t *self_p)

Get the number of input bytes currently stored in the socket. May return less bytes than number of bytes stored in the channel.

Return
Number of input bytes in the socket.
Parameters
  • self_p: Socket.

struct socket_t

Public Members

struct chan_t base
int type
ssize_t left
struct socket_t::@59::@61::@63 socket_t::common
struct pbuf *pbuf_p
struct inet_addr_t remote_addr
int closed
struct socket_t::@59::@61::@64 socket_t::recvfrom
struct tcp_pcb *pcb_p
struct socket_t::@59::@61::@65 socket_t::accept
union socket_t::@59::@61 socket_t::u
int state
void *args_p
struct thrd_t *thrd_p
struct socket_t::@59::@62 socket_t::cb
struct socket_t::@59 socket_t::input
struct socket_t::@60::@66 socket_t::cb
struct socket_t::@60 socket_t::output
void *pcb_p