D. J. Bernstein

The socket library interface

TCP client sockets

     #include <socket.h>

     s = socket_tcp();
     socket_bind4(s,ip,p);
     socket_connect4(s,ip,p);
     socket_connected(s);

     int s;
     char ip[4];
     uint16 p;
socket_tcp creates a non-blocking TCP/IP stream socket and returns a file descriptor pointing to that socket. If something goes wrong, socket_tcp returns -1, setting errno appropriately, without allocating any resources.

socket_bind4 sets the local IP address and TCP port of TCP socket s to ip and p respectively. If the IP address is 0.0.0.0, the operating system chooses a local IP address. If the TCP port is 0, the operating system chooses a TCP port. Normally socket_bind4 returns 0. If anything goes wrong, socket_bind4 returns -1, setting errno appropriately.

socket_connect4 attempts to make a connection from TCP socket s to TCP port p on IP address ip. socket_connect4 may return

When a background connection succeeds or fails, s becomes writable; you can use socket_connected to see whether the connection succeeded. If the connection failed, socket_connected returns 0, setting errno appropriately.

Once a TCP socket is connected, you can use the read and write system calls to transmit data.

You can call socket_connect4 without calling socket_bind4. This has the same effect as first calling socket_bind4 with IP address 0.0.0.0 and TCP port 0.

TCP server sockets

     #include <socket.h>

     socket_bind4_reuse(s,ip,p);
     socket_listen(s,n);
     fd = socket_accept4(s,ip,&p);

     int fd;
     int s;
     char ip[4];
     uint16 p;
     int n;
socket_bind4_reuse is like socket_bind4 but allows the same TCP port number to be reused immediately after the socket is closed. socket_bind4_reuse is best for servers; socket_bind4 is best for clients.

socket_listen prepares TCP socket s to accept TCP connections. It allows a backlog of approximately n TCP SYNs. (On systems supporting SYN cookies, the backlog is irrelevant.) Normally socket_listen returns 0. If anything goes wrong, socket_listen returns -1, setting errno appropriately.

When a TCP connection arrives on a listening TCP socket s, the socket becomes readable. socket_accept4 accepts the connection. It sets ip and p to the client IP address and client TCP port. It creates a new socket for the connection, and returns a file descriptor pointing to the new socket; you can use the read and write system calls to transmit data through that file descriptor. If something goes wrong, socket_accept4 returns -1, setting errno appropriately, without creating a new socket.

UDP sockets

     #include <socket.h>

     s = socket_udp();
     socket_send4(s,buf,len,ip,p);
     socket_recv4(s,buf,len,ip,&p);
     socket_tryreservein(s,n);

     int s;
     char ip[4];
     uint16 p;
     char *buf;
     int len;
     int n;
socket_udp creates a non-blocking UDP/IP datagram socket and returns a file descriptor pointing to that socket. If something goes wrong, socket_udp returns -1, setting errno appropriately, without allocating any resources.

You can use socket_bind4 or socket_bind4_reuse to set the IP address and UDP port of a UDP socket.

socket_send4 sends a datagram through UDP socket s to UDP port p of IP address ip. The datagram contains bytes buf[0], buf[1], ... buf[len-1]. Normally socket_send4 returns a nonnegative number. If something goes wrong, socket_send4 returns -1, setting errno appropriately.

socket_recv4 receives a datagram through UDP socket s. It sets ip and p to the sender IP address and sender UDP port listed in the datagram. It copies the datagram into buf[0], buf[1], ..., and returns the number of bytes in the datagram. If the datagram is longer than len bytes, socket_recv4 stores only the first len bytes, and returns len or more. If something goes wrong, socket_recv4 returns -1, setting errno appropriately.

socket_tryreservein attempts to allocate n bytes of incoming UDP buffer space for UDP socket s.