🟨 Synchronous socket networking and DNS lookup
SaneCppSocket.h is a library implementing synchronous socket networking and DNS lookup.
Dependencies
- Dependencies: (none)
- All dependencies: (none)

Features
Details
Status
🟨 MVP
Simple synchronous TCP client / server workflow is supported, but it would need better testing.
Blog
Some relevant blog posts are:
Description
SocketDescriptor
It also allow querying inheritability and changing it (and blocking mode)
Example (extracted from unit test):
bool isInheritable;
SC_TEST_EXPECT(socket.
create(SocketFlags::AddressFamilyIPV4, SocketFlags::SocketStream, SocketFlags::ProtocolTcp,
SocketFlags::NonBlocking, SocketFlags::NonInheritable));
isInheritable = false;
SC_TEST_EXPECT(socket.
create(SocketFlags::AddressFamilyIPV4, SocketFlags::SocketStream, SocketFlags::ProtocolTcp,
SocketFlags::Blocking, SocketFlags::NonInheritable));
isInheritable = false;
SC_TEST_EXPECT(socket.
create(SocketFlags::AddressFamilyIPV4, SocketFlags::SocketStream, SocketFlags::ProtocolTcp,
SocketFlags::Blocking, SocketFlags::Inheritable));
isInheritable = false;
SocketServer
Example:
constexpr int tcpPort = 5050;
SC_TRY(serverSocket.
create(family));
SC_TRY(server.bind(nativeAddress));
SC_TRY(server.listen(1));
SC_TRY(server.accept(family, acceptedClientSocket));
SC_TRY(acceptedClientSocket.isValid());
SocketClient
The socket client can be obtained via SC::SocketServer::accept or connected to an endpoint through SC::SocketClient::connect.
Example (accepted client from server, doing a synchronous read):
SC_TRY(server.accept(family, acceptedClientSocket));
SC_TRY(acceptedClientSocket.isValid());
char buf[256];
Span<char> readData;
SC_TRY(acceptedClient.read({buf, sizeof(buf)}, readData));
SC_TRY(acceptedClient.readWithTimeout({buf, sizeof(buf)}, readData, 10 * 1000));
SC_TRY(acceptedClientSocket.close());
Example (connecting client to server, doing two synchronous writes):
SC_TRY(clientSocket.
create(family));
SC_TRY(client.connect(serverAddress, tcpPort));
const int testValue = 1;
char buf[1] = {testValue};
SC_TRY(client.write({buf, sizeof(buf)}));
buf[0]++;
SC_TRY(client.write({buf, sizeof(buf)}));
SC_TRY(clientSocket.close());
SocketIPAddress
Example:
const char badMemory[] = "oh yeah that's a really broken socket ip address";
const auto& badIPAddress = *
reinterpret_cast<const SocketIPAddress*
>(&badMemory);
SocketDNS
Example:
char buffer[256] = {0};
Span<char> ipAddress = {buffer};
Roadmap
🟩 Usable
- Add UDP specific socket operations
🟦 Complete Features:
💡 Unplanned Features:
Statistics
| Type | Lines Of Code | Comments | Sum |
| Headers | 145 | 225 | 370 |
| Sources | 894 | 156 | 1050 |
| Sum | 1039 | 381 | 1420 |