Skip to content
lupaxa-developers-toolboxPublic

About

C library for IPv4 and IPv6 TCP and UDP sockets.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Developers Toolbox

Libsocket

C library for IPv4 and IPv6 TCP and UDP sockets.

A caller passes an explicit address to bind, and keeps the descriptor for select. Listening sockets and accepted sockets are non-blocking. A connected TCP socket and a UDP socket stay blocking. The public header is include/socket.h. It uses C linkage, so a C++ translation unit can include it.

Requirements

  • GNU make.
  • gcc, unless CC is set. The C skill uses gcc for syntax checks.
  • cppcheck, for make c-check.

Build

make lib writes the static archive build/libsocket.a. The archive is built as C11 with -Wall -Wextra -Wpedantic -Werror. The compiler is gcc unless CC is set. make clean removes build/.

make lib
cc -std=c11 -Iinclude -o demo demo.c build/libsocket.a

make lib CC=clang selects the compiler. make lib CFLAGS=-g adds flags to that C11 build. make with no target prints the makefile help.

make update refreshes the makefile skills. make lib and make test do not need that checkout. make c-check and make version do.

Quick Start

Listen on the IPv4 loopback address and connect to it.

#include "socket.h"

int main(void)
{
    int listener = -1;
    int client = -1;

    if (socket_tcp_listen(&listener, "127.0.0.1", 4545, 16) != SOCKET_OK) {
        return 1;
    }
    if (socket_tcp_connect(&client, "127.0.0.1", 4545) != SOCKET_OK) {
        socket_close(&listener);
        return 1;
    }

    socket_close(&client);
    socket_close(&listener);
    return 0;
}

Port 0 lets the system choose the port. socket_tcp_accept takes the queued connection. The listening descriptor stays open.

Addresses

Bind takes a numeric address. A host name is rejected.

Address Bind result
127.0.0.1 That IPv4 address
0.0.0.0 Every IPv4 interface
::1 That IPv6 address
:: Every IPv6 interface
fe80::1%lo0 That link-local address and zone

An IPv6 socket is IPv6 only, so :: does not accept IPv4. socket_ipv4 and socket_ipv6 report whether a text is that kind of address. *valid is 1 or 0.

socket_tcp_connect takes a name or a numeric address and tries each IPv4 and IPv6 result.

Note: Callers serialise use of a given descriptor. New descriptors are close-on-exec.

TCP

socket_tcp_listen sets SO_REUSEADDR, makes the socket non-blocking, and listens. socket_tcp_accept returns SOCKET_AGAIN when nothing is queued. The accepted socket is non-blocking and has keepalive enabled.

socket_tcp_read reads once. End of file is success and *got is 0. No data on a non-blocking socket is SOCKET_AGAIN. The call does not close the socket and does not add a NUL.

socket_tcp_write writes until the buffer is finished, the socket would block, or a real error occurs. *sent is how many bytes were accepted. A length of 0 writes nothing.

UDP

socket_udp_bind binds one blocking UDP socket. It uses the same address rules as socket_tcp_listen. Sending and receiving stay with the caller.

Return Codes

Code Value Meaning
SOCKET_OK 0 The call succeeded.
SOCKET_INVAL -2 An argument is missing or unusable. Out-pointers stay unchanged.
SOCKET_IO -3 A system call failed.
SOCKET_AGAIN -4 A non-blocking socket cannot finish yet.

socket_close(NULL) returns SOCKET_INVAL. Descriptors 0, 1, and 2 stay open. A descriptor that is already -1 is success. After a successful close, *fd is -1.

Functions

int socket_ipv4(const char *text, int *valid);
int socket_ipv6(const char *text, int *valid);
int socket_tcp_listen(int *fd, const char *address, unsigned short port,
                      int backlog);
int socket_tcp_accept(int listen_fd, int *fd);
int socket_tcp_connect(int *fd, const char *host, unsigned short port);
int socket_tcp_read(int fd, void *buffer, size_t capacity, size_t *got);
int socket_tcp_write(int fd, const void *buffer, size_t length, size_t *sent);
int socket_udp_bind(int *fd, const char *address, unsigned short port);
int socket_close(int *fd);
Name Purpose
socket_ipv4 Report whether a text is an IPv4 address.
socket_ipv6 Report whether a text is an IPv6 address.
socket_tcp_listen Bind a non-blocking listening socket.
socket_tcp_accept Accept one non-blocking connection.
socket_tcp_connect Connect a blocking socket.
socket_tcp_read Read once from a TCP socket.
socket_tcp_write Write a buffer to a TCP socket.
socket_udp_bind Bind a blocking UDP socket.
socket_close Close a descriptor and store -1.

Version

The version text is the macro SOCKET_VERSION_STRING in include/socket.h. It is a dotted semantic version. .bumpversion.toml is the version source, and a bump updates that macro.

After make init, make version prints the version from .bumpversion.toml.

Development

make update
make lib
make check
make clean

make c-check syntax-checks every .c and .h file, then runs cppcheck. make check runs c-check and then the behaviour tests. make test runs only the behaviour tests.

The Lupaxa Project Footer

About

C library for IPv4 and IPv6 TCP and UDP sockets.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages