Implementation:ClickHouse ClickHouse Poco Socket
| Knowledge Sources | |
|---|---|
| Domains | Networking, Sockets |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
Common base class for socket types providing unified interface for socket operations, configuration, and I/O readiness polling.
Description
The Poco `Socket` class serves as the common base for specialized socket types (`StreamSocket`, `ServerSocket`, `DatagramSocket`). It provides a reference-counted wrapper around `SocketImpl` and offers methods common to all sockets: configuration (buffer sizes, timeouts, socket options), I/O readiness checking (`select`, `poll`), connection management, and throttling support.
The class uses the pimpl idiom with `SocketImpl` for the actual socket implementation, allowing lightweight copying of socket objects that share the same underlying socket descriptor. It supports both blocking and non-blocking modes, comprehensive socket option management, and cross-platform socket operations.
Usage
ClickHouse uses this as the foundation for all socket-based networking operations. The `Socket` class provides the common interface that enables polymorphic handling of different socket types throughout the networking stack.
Code Reference
Source Location
- Repository: ClickHouse
- File: base/poco/Net/include/Poco/Net/Socket.h
- Lines: 1-692
Signature
class Socket {
public:
enum SelectMode {
SELECT_READ = 1,
SELECT_WRITE = 2,
SELECT_ERROR = 4
};
typedef std::vector<Socket> SocketList;
Socket();
Socket(const Socket& socket);
Socket& operator=(const Socket& socket);
virtual ~Socket();
bool operator==(const Socket& socket) const;
bool operator!=(const Socket& socket) const;
bool operator<(const Socket& socket) const;
void shutdownReceive();
void shutdownSend();
void shutdown();
void close();
static int select(SocketList& readList, SocketList& writeList,
SocketList& exceptList, const Poco::Timespan& timeout);
bool poll(const Poco::Timespan& timeout, int mode) const;
int available() const;
void setSendBufferSize(int size);
int getSendBufferSize() const;
void setReceiveBufferSize(int size);
int getReceiveBufferSize() const;
void setSendTimeout(const Poco::Timespan& timeout);
Poco::Timespan getSendTimeout() const;
void setReceiveTimeout(const Poco::Timespan& timeout);
Poco::Timespan getReceiveTimeout() const;
void setSendThrottler(const ThrottlerPtr& throttler);
ThrottlerPtr getSendThrottler() const;
void setReceiveThrottler(const ThrottlerPtr& throttler);
ThrottlerPtr getReceiveThrottler() const;
void setOption(int level, int option, int value);
void setOption(int level, int option, unsigned value);
void setOption(int level, int option, const Poco::Timespan& value);
void setOption(int level, int option, const IPAddress& value);
void getOption(int level, int option, int& value) const;
void getOption(int level, int option, Poco::Timespan& value) const;
void setLinger(bool on, int seconds);
void getLinger(bool& on, int& seconds) const;
void setNoDelay(bool flag);
bool getNoDelay() const;
void setKeepAlive(bool flag);
bool getKeepAlive() const;
void setReuseAddress(bool flag);
bool getReuseAddress() const;
void setReusePort(bool flag);
bool getReusePort() const;
void setOOBInline(bool flag);
bool getOOBInline() const;
void setBlocking(bool flag);
bool getBlocking() const;
SocketAddress address() const;
SocketAddress peerAddress() const;
SocketImpl* impl() const;
bool secure() const;
static bool supportsIPv4();
static bool supportsIPv6();
void init(int af);
poco_socket_t sockfd() const;
};
Import
#include <Poco/Net/Socket.h>
I/O Contract
| Input | Output |
|---|---|
| Socket configuration options | Configured socket with specified behavior |
| Timeout values | Socket with timeout enforcement |
| Poll/select with timeout and mode | Boolean indicating I/O readiness |
| Multiple socket lists for select | Updated lists with ready sockets |
Socket Options
| Option | Description |
|---|---|
| `setNoDelay` | Disable Nagle's algorithm (TCP_NODELAY) |
| `setKeepAlive` | Enable TCP keep-alive (SO_KEEPALIVE) |
| `setReuseAddress` | Allow address reuse (SO_REUSEADDR) |
| `setReusePort` | Allow port reuse (SO_REUSEPORT) |
| `setLinger` | Control socket close behavior (SO_LINGER) |
| `setOOBInline` | Inline out-of-band data (SO_OOBINLINE) |
| `setBlocking` | Blocking vs. non-blocking mode |
Usage Examples
// Create and configure a stream socket
StreamSocket socket;
socket.connect(SocketAddress("example.com", 80));
// Configure socket options
socket.setNoDelay(true); // Disable Nagle
socket.setKeepAlive(true); // Enable keep-alive
socket.setReuseAddress(true);
// Set timeouts
socket.setSendTimeout(Poco::Timespan(30, 0)); // 30 seconds
socket.setReceiveTimeout(Poco::Timespan(30, 0));
// Set buffer sizes
socket.setSendBufferSize(64 * 1024); // 64 KB
socket.setReceiveBufferSize(64 * 1024);
// Check if data is available
if (socket.available() > 0) {
// Data ready to read
}
// Poll for I/O readiness
Poco::Timespan timeout(1, 0); // 1 second
if (socket.poll(timeout, Socket::SELECT_READ)) {
// Socket is readable
}
if (socket.poll(timeout, Socket::SELECT_WRITE)) {
// Socket is writable
}
// Use select with multiple sockets
Socket::SocketList readList, writeList, exceptList;
readList.push_back(socket1);
readList.push_back(socket2);
writeList.push_back(socket3);
int ready = Socket::select(readList, writeList, exceptList,
Poco::Timespan(5, 0));
// readList now contains only sockets ready for reading
for (const auto& sock : readList) {
// Read from ready socket
}
// Set throttling
auto throttler = std::make_shared<Throttler>(1024 * 1024); // 1 MB/s
socket.setSendThrottler(throttler);
socket.setReceiveThrottler(throttler);
// Query addresses
SocketAddress local = socket.address();
SocketAddress remote = socket.peerAddress();
std::cout << "Local: " << local.toString() << std::endl;
std::cout << "Remote: " << remote.toString() << std::endl;
// Graceful shutdown
socket.shutdownSend(); // No more sending
// ... read remaining data ...
socket.shutdownReceive(); // No more receiving
socket.close();
// Check platform support
if (Socket::supportsIPv6()) {
std::cout << "IPv6 supported" << std::endl;
}
// Access underlying socket descriptor
poco_socket_t fd = socket.sockfd();