sockpp wraps Berkeley sockets with RAII and result<T> error handling
Modern C++ socket library.
At a glance
- What is it?
- sockpp is a C++17 wrapper around the Berkeley sockets library that gives you socket, acceptor and connector classes with automatic handle lifetime and error returns instead of exceptions or cached errno. Its TLS, SocketCAN and Windows UNIX socket support is explicitly experimental, and its master branch is a moving target for the 2.0 API.
- Who is it for?
- Adopt sockpp when you are writing networked C++ on Linux, macOS or Windows and want typed connectors and acceptors with ownership that transfers cleanly between threads. Do not adopt it if you need stable TLS or CAN bus support today, because those parts are experimental, are not held to semantic versioning, and are stated to be not production ready.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 96 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A thin wrapper with a modern ownership model
sockpp is described as a fairly low-level C++ wrapper around the Berkeley sockets library, using socket, acceptor and connector classes that are familiar concepts from other languages. Low level is the right word. This is not a framework with an event loop, a connection manager or an HTTP layer. It is the socket API with a C++ interface, and the value it adds is in how the handle is owned and how errors are returned. The base socket class wraps a system socket handle and maintains its lifetime using the familiar RAII pattern, so when the C++ object goes out of scope it closes the underlying socket handle. Socket objects are generally moveable but not copyable, and a socket can be transferred from one scope or thread to another using std::move(). That move semantics detail is the part that matters in practice. A socket is a resource, and C++ code that hands a resource between threads usually needs either a shared pointer or a discipline about who closes it. Move-only ownership makes the handoff explicit: the moved-from object no longer owns the descriptor, so there is exactly one owner at every point in the program. There is a second ownership path. clone() produces an independent duplicate, which is the way to hand a descriptor to another process without the awkwardness of transferring ownership. All code in the library lives within the sockpp namespace, and the README notes that the namespace is Sockpp when the library is consumed through CMake, a small detail that trips people up when they write their own using declarations.
result<T> returns an error code instead of throwing
The error handling model is the second design decision, and it is the more opinionated one. The README describes a result<T> error handling approach where API calls return a result<> instead of throwing or setting a cached error code. It carries either a success value or a std::error_code, it supports comparison against error constants with !=, and it exposes a release() move accessor. There is no exception dependency. This is a real departure from the C socket convention. The usual pattern is a function that returns -1 and leaves the reason in a global errno that you have to copy immediately, before the next call overwrites it. The library instead returns the reason as part of the return value, so it cannot be lost by accident. There is also a stateless read() and write() variant for the datagram and stream sockets that do not cache error state at all, which the features list calls out explicitly. The two views coexist, which is worth understanding. The result<T> approach is the modern one, and it is part of the stated goal for the 2.0 work: a major refactor of error handling to allow apps to use the library without exceptions. The stateless read and write variants give you the classic behaviour when you want it. Because the error is a std::error_code rather than a string, comparisons are against error constants, which means the checks read as intent rather than as integer comparisons.
Typed connectors and acceptors, and a portable poller
The class hierarchy is built around typed templates so the address family and protocol are part of the type. The TCP support lists typed connector and acceptor templates such as tcp_connector and tcp6_acceptor built on a common base, and udp_socket and udp6_socket for datagram use. Raw sockets are there too, for low level protocols or control. The connector and acceptor options are the part that turns a thin wrapper into something you would actually build on. There are optional connect and accept timeouts, cross-platform through the poller, configurable SO_REUSEADDR and SO_REUSEPORT, a customizable protocol value, and socket handle cleanup on a failed connect. That last one matters, because a connect that fails after the socket was created leaves you with a descriptor to close, and the library handles it. The poller is the other headline feature. It is a platform-independent class that waits for events on a collection of socket objects, with an optional timeout. On Linux that is an epoll shaped job, on macOS a kqueue shaped job, and on Windows something else, but the interface is the same. A poller with a timeout plus acceptors with accept timeouts gives you a server loop without platform specific code. That combination is the reason to pick this library over writing raw socket calls. The network address classes are equally broad: IPv4, IPv6, UNIX-domain, SocketCAN on Linux, and a generic network address type for anything else.
TLS, CAN bus and Windows UNIX sockets are labelled experimental
The README is unusually candid about which parts of the library you should trust, and the experimental section deserves to be read before the features list. The experimental TLS support has a compile-time choice of OpenSSL or mbedTLS implementations behind a common interface. A tls_context configures trust locations, certificates and private keys, and tls_connector and tls_acceptor wrap standard stream sockets. It supports ALPN, PSK, cipher suite control, graceful shutdown and peer certificate inspection. The X.509 side exposes tls_certificate with subject and issuer names, SANs, serial number, fingerprint, validity window and PEM export, plus tls_certificate_chain as an ordered collection, leaf first, with structural validity checking and PEM import and export. SocketCAN support covers classic CAN and CAN FD on Linux, with frame conversion between the two formats, address validation, and a canbus_socket::recv() that rejects FD frames on a classic socket. That last behaviour is the kind of detail that shows the author has actually used the hardware. UNIX-domain sockets on Windows work on Windows 11 and later versions of Windows 10, and the README is explicit that Windows only supports UNIX stream sockets with no datagram support. Then the warning, in capitals worth heeding: experimental features are incomplete and not fully tested, their APIs are not final and could change in updates for the same major version, so they are not held to the constraints of semantic versioning, and they are not production ready. On Linux, UNIX-domain sockets are already fully supported, with pairs, abstract-namespace addresses and max-length path handling.
Building with CMake: one find_package and one target
Consuming the library is a small CMake project.
cmake_minimum_required(VERSION 3.15)
project(mysock VERSION 1.0.0)
find_package(sockpp REQUIRED)
add_executable(mysock mysock.cpp)
target_link_libraries(mysock Sockpp::sockpp)Once installed, the library can normally be discovered with find_package(sockpp), and the imported target is Sockpp::sockpp. The names line up: the package is sockpp, the namespace is Sockpp and the library is sockpp. The repository also ships a conanfile.py, so the same library is consumable through Conan as well as through a plain CMake install. The build files include a CMakeLists.txt at the root plus a cmake/ directory, a config/ directory for the installed package configuration, and a Doxyfile for API documentation generation. There are examples to read. The examples directory has its own CMakeLists.txt and separate folders for tcp, udp, unix, tls and linux specific code, which is a faster way to understand the intended usage than the documentation, since the README notes the mdBook documentation is still in its infancy. The C++ level to target is stated in the feature list as C++17 with some C++20 features. The C++20 part is the span<byte> I/O overloads, where read(), write(), send() and recv() accept a std::span<byte> for bounds-safe, zero-copy buffer passing. If you compile with C++17 those overloads are simply not available, and the rest of the library works.
Master is unstable, and releases stopped in 2023
The version story needs to be understood before you pick a source. The README states plainly that the master branch is moving toward the v2.0 API, and is particularly unstable at the moment, and advises downloading the latest release for production use. That is a specific warning from the author, and it is the opposite of the usual advice to track the main branch. The 2.0 goals are listed in the README: move the library to C++17 with optional C++20 support through spans for I/O, do a major refactor of error handling so apps can use the library without exceptions, achieve better and easier thread safety, add a portable socket poller class, add MinGW-w64 support on Windows, fix a number of known bugs and build issues, start better documentation particularly for new users, and start experimental support for secure TLS sockets, SocketCAN on Linux and optionally Bluetooth on Linux. Most of that list is already visible in the current feature list, which tells you how far the work has progressed. The tagged releases tell a different story. The newest is v1.0.0 from 2023-12-17, before that v0.8.3 and v0.8.2 from the same week in December 2023. The last push to the repository was on 2026-07-19, so commits continue, but no release has been cut in more than two and a half years. The practical read is that a released 1.0.0 will not have the poller, the result<T> model, or the experimental features that the current tree has. If you need those, you are building against master and accepting the instability the README warns about.
BSD-3-Clause, and pull requests that go to develop
The licence field on the repository says BSD-3-Clause, with a LICENSE file at the root. That is a permissive licence with the three clause structure, which is the easy case for both commercial and open source use, provided you keep the copyright notice and the disclaimer. The contribution model has a specific rule that trips people up. New and unstable work is done in the develop branch, and the README asks you to submit all pull requests against that branch, not master. Since master is itself the unstable v2.0 line, the distinction matters: develop is where in progress changes land, master is where the 2.0 rework lives, and releases are cut from somewhere stable. The repository structure supports the same split. There is a CHANGELOG.md, a CONTRIBUTING.md, a .clang-format file and an .editorconfig, a Doxyfile for generated API docs, a doc/ directory and an fmp-doc/ directory, a scripts/ directory, a test-keys/ directory for the TLS material, a tests/ directory and a buildtst.sh script, plus a .hgeol configuration and a _typos.toml for the spell checker. The project also publishes its documentation as an mdBook at fpagliughi.github.io/sockpp, which the README describes as still in its infancy but potentially helpful. Announcements go out on Mastodon at @[email protected], and the README invites users to send a message describing where the library ends up in their project.
Editorial conclusion
Adopt sockpp when you are writing networked C++ on Linux, macOS or Windows and want typed connectors and acceptors with ownership that transfers cleanly between threads. Do not adopt it if you need stable TLS or CAN bus support today, because those parts are experimental, are not held to semantic versioning, and are stated to be not production ready. Before you start, install the latest release rather than tracking master, because the README says master is particularly unstable while the 2.0 API work continues.
Frequently asked questions
What is sockpp and which platforms does it support?
sockpp is a fairly low-level C++ wrapper around the Berkeley sockets library using socket, acceptor and connector classes. It supports IPv4 and IPv6 on Linux, Mac and Windows, and other Unix and POSIX systems should work with little or no modification.
How does sockpp handle errors?
API calls return a result<T> that carries either a success value or a std::error_code, instead of throwing or setting a cached error code. It supports comparison against error constants and a release() move accessor, and there is no exception dependency.
Is the TLS support in sockpp ready for production?
No. The README lists TLS with the OpenSSL and mbedTLS backends under experimental features, and states that experimental features are incomplete, not fully tested, not held to the constraints of semantic versioning, and not production ready.
How do I link sockpp in my CMake project?
Use find_package(sockpp REQUIRED) and link against the imported target Sockpp::sockpp, with cmake_minimum_required of at least 3.15. A Conan recipe is also provided in conanfile.py.
Should I build sockpp from the master branch?
Not for production. The README says the master branch is moving toward the v2.0 API and is particularly unstable at the moment, and advises downloading the latest release for production use. Pull requests should target the develop branch rather than master.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/fpagliughi-sockpp)Was this useful?