eve.aio.windows.tcp
Async TCP listener and connection primitives for Windows.
This module provides the Windows implementation of TCP networking primitives using Winsock2 API with IOCP overlapped I/O support.
Backpressure is modelled via an all-or-nothing send policy: send() either accepts all bytes (OK) or rejects with PRESSURE. A per-connection send queue buffers data until the kernel can drain it. When the queue drains below the low water mark, onWritable fires.
Two I/O modes are available:
- WSAPoll mode (default) — synchronous non-blocking I/O with edge
notifications via the event loop poller.
- IOCP_OVERLAPPED mode — true asynchronous I/O using AcceptEx,
ConnectEx, WSARecv/WSASend with IOCP completion polling.
See Also
Types 16
Connection-side buffer configuration.
size_t highWaterMarkMaximum queued bytes before `send` starts reporting pressure.size_t lowWaterMarkQueue threshold below which `onWritable` may fire again.int recvBufferSizeSocket receive buffer size in bytes. 0 = use OS default.int sendBufferSizeSocket send buffer size in bytes. 0 = use OS default.bool keepAliveEnabledEnable TCP keepalive probes.uint keepAliveIdleTime in milliseconds before the first keepalive probe. Default: 60s.uint keepAliveIntervalTime in milliseconds between keepalive probes. Default: 10s.Listener-side socket configuration.
int backlogPending accept backlog passed to `listen`.int concurrentAcceptsNumber of concurrent `AcceptEx` operations to keep pending.Async TCP connection wrapper.
Wraps a non-blocking TCP socket and integrates with the Layer 1 event loop for async read/write operations with backpressure support.
private TcpConnectionState _stateTcpConnection create(TcpConnectionConfig config = TcpConnectionConfig.init) static @trusted nothrowCreate a detached connection wrapper.void onConnect(ConnectCallback callback) @property @trusted Set the connect callback. Fires once when the TLS/TCP handshake completes successfully. Thread affinity: event loop thread only. Non-reentrant. Does not fire after `dispose()`. Params: ...void onData(DataCallback callback) @property @trusted Set the inbound data callback. Fires when data arrives. The `data` parameter is borrowed — valid only for the duration of the callback. Copy it if needed beyond. Thread affinity: event loop ...void onWritable(WritableCallback callback) @property @trusted Set the writable callback. Fires when the send queue drains below the low water mark after backpressure. Not called on initial connect. Thread affinity: event loop thread only. Non-reentrant. ...void onClose(CloseCallback callback) @property @trusted Set the close callback. Fires when the remote end closes the connection or a fatal error occurs. May fire after `close()` if data was still pending. Does not fire after `dispose()`. Thread af...void onError(ErrorCallback callback) @property @trusted Set the error callback. Fires on connection errors. After this callback, the connection enters an error state; `onClose` may or may not follow. Thread affinity: event loop thread only. Non-ree...bool isOpen() @property const @safe nothrow @nogcReport whether the wrapper currently owns an open socket.bool isWritable() @property const @safe nothrow @nogcReport whether the connection is currently writable from the caller's perspective.IpAddress remoteAddress() @property const @safe nothrow @nogcReport the remote address of the connection.IpAddress localAddress() @property const @safe nothrow @nogcReport the local address of the connection.AdoptResult adopt(ref EventLoop loop, Handle clientHandle) @trusted nothrowAdopt an already-accepted client socket.ConnectResult connect(ref EventLoop loop, scope const(char)[] host, ushort port, CancelToken cancel = CancelToken
.invalid) @trusted nothrowStart a non-blocking connection attempt.SendResult sendFile(HANDLE fileHandle, ulong offset, size_t count) @trusted nothrowSend a file over the connection using zero-copy TransmitFile.bool track(Coord)(ref Coord coordinator) @trusted nothrowTrack this connection for graceful shutdown.Async TCP listener wrapper.
Wraps a non-blocking TCP listening socket and integrates with the Layer 1 event loop for async accept operations.
private TcpListenerState _stateTcpListener create(TcpListenerConfig config = TcpListenerConfig.init) static @trustedCreate a detached listener wrapper.void onAccept(AcceptCallback callback) @property @trusted Set the accept callback. Fires when a new client connection is accepted. The `clientHandle` is *caller-owned — you must call `TcpConnection.adopt()` to take ownership, or close it via `close...void onConnection(ConnectionCallback callback) @property @trustedSet the high-level connection callback.void onError(ListenerErrorCallback callback) @property @trustedSet the error callback for accept failures.bool isOpen() @property const @safe nothrow @nogcReport whether the listener currently owns an open socket.ushort localPort() @property const @safe nothrow @nogcReport the effective local port once listening.ListenResult listen(ref EventLoop loop, scope const(char)[] host, ushort port) @trustedStart listening on the requested endpoint.ConnectCallback onConnectDataCallback onDataWritableCallback onWritableCloseCallback onCloseErrorCallback onErrorprivate EventLoop * _loopprivate SOCKET _socketprivate Token _tokenprivate TcpConnectionConfig _configprivate bool _readingPausedprivate bool _watchingWriteprivate bool _awaitingWritableprivate bool _closeDeliveredprivate ubyte[] _sendQueueprivate SocketState _stateprivate int _lastErrorprivate IpAddress _remoteAddressprivate IpAddress _localAddressprivate CancelToken _cancelTokenprivate CancelToken _shutdownTokenprivate bool _drainingprivate bool _useOverlappedIoWhether this connection uses overlapped I/O mode.private Token _prepareTokenPrepare token for polling IOCP completion status.private OVERLAPPED _readOverlappedOverlapped structure for pending read operations.private OVERLAPPED _writeOverlappedOverlapped structure for pending write operations.private ubyte[TCP_READ_BUFFER_SIZE] _readBufferRead buffer — must remain valid during overlapped read.private ubyte[TCP_READ_BUFFER_SIZE] _writeBufferWrite buffer — must remain valid during overlapped write.private bool _readInProgressWhether a read operation is currently in progress.private bool _writeInProgressWhether a write operation is currently in progress.private size_t _pendingWriteLenNumber of bytes in the current pending write.private ConnectExFunc _connectExConnectEx function pointer (loaded on first use).private OVERLAPPED _connectOverlappedOverlapped structure for pending connect operation.private bool _connectInProgressWhether a connect operation is currently in progress.private ubyte[] _pausedReceiveBufferBuffer for data received while reading is paused (IOCP mode only). When paused, incoming data is stored here instead of being delivered.private TransmitFileFunc _transmitFileFuncTransmitFile function pointer (loaded on first use).private HANDLE _sendFileHandleFile handle for in-progress file transfer.private OVERLAPPED _sendFileOverlappedOverlapped structure for pending TransmitFile operation.private ulong _sendFileOffsetCurrent byte offset in the file being transferred.private size_t _sendFileRemainingRemaining bytes to transfer (0 = send until EOF).private bool _sendFileInProgressWhether a TransmitFile operation is currently in progress.private bool _sendFileCloseAfterWhether to close the file handle after transfer completes.ConnectResult connect(ref EventLoop loop, scope const(char)[] host, ushort port, CancelToken cancel = CancelToken
.invalid) @trusted nothrowint bindToAnyAddress(SOCKET sock, int family) @trusted nothrowBind socket to any available local address.int submitConnectEx(const(sockaddr) * addr, int addrlen) @trusted nothrowSubmit a ConnectEx operation.SendResult sendFile(HANDLE fileHandle, ulong offset, size_t count) @trusted nothrowSend a file over the connection using zero-copy TransmitFile.void processTransmitFileCompletion() @trusted nothrowProcess a completed TransmitFile operation (IOCP overlapped mode).void finishFileTransfer(bool error) @trusted nothrowClean up after a file transfer completes or fails.void closeInternal(SocketCloseReason reason, int errorNumber, bool invokeCallback) @trusted nothrowvoid handlePrepare(ref EventLoop loop, Token token) @trusted nothrowHandle prepare phase callback from the event loop.void submitRecv() @trusted nothrow Submit an overlapped receive operation. Initiates an asynchronous receive on the socket. The operation will complete via IOCP, and the prepare handler will process the result. * Only one receiv...void consumeSendQueue(size_t count) @trusted nothrow @nogcRemove `count` bytes from the front of `sendQueue` without allocating.this(TcpConnectionConfig config)AcceptCallback onAcceptConnectionCallback onConnectionListenerErrorCallback onAcceptErrorprivate EventLoop * _loopprivate SOCKET _socketprivate Token _tokenprivate TcpListenerConfig _configprivate ushort _localPortprivate int _lastErrorprivate CancelToken _shutdownTokenprivate bool _drainingprivate bool _useOverlappedIoWhether this listener uses overlapped I/O mode (AcceptEx).private Token _prepareTokenPrepare token for polling IOCP completion status.private AcceptExFunc _acceptExAcceptEx function pointer.private GetAcceptExSockaddrsFunc _getAcceptExSockaddrsGetAcceptExSockaddrs function pointer.private int _addressFamilyAddress family of the listen socket (AF_INET or AF_INET6).private AcceptSlot[] _acceptSlotsArray of concurrent accept operation slots.void handlePrepare(ref EventLoop loop, Token token) @trusted nothrowHandle prepare phase callback from the event loop.int associateWithIocp() @trusted nothrowAssociate the listen socket with the event loop's IOCP.void submitAcceptToSlot(ref AcceptSlot slot) @trusted nothrowSubmit an AcceptEx operation to a specific slot.void processAcceptCompletion(ref AcceptSlot slot) @trusted nothrowProcess a completed AcceptEx operation for a specific slot.this(TcpListenerConfig config)Per-accept operation state for concurrent AcceptEx.
Each slot maintains independent state for one pending AcceptEx call, allowing multiple accepts to be in flight simultaneously.
SOCKET acceptSocketPre-created socket for this pending accept operation.OVERLAPPED overlappedOverlapped structure for this pending accept operation.ubyte[ACCEPT_BUFFER_SIZE] bufferBuffer for AcceptEx output (local + remote addresses).bool inProgressWhether an accept operation is currently in progress in this slot.Range adapter for iterating over addrinfo linked list.
addrinfo * currentFunctions 16
ListenResult mapListenError(int err) pure @safe nothrow @nogcMap Winsock error code to ListenResult.ConnectResult mapConnectError(int err) pure @safe nothrow @nogcMap Winsock error code to ConnectResult.AdoptResult mapAdoptError(int err) pure @safe nothrow @nogcMap Winsock error code to AdoptResult.TcpConnectionConfig validated(TcpConnectionConfig config) pure @safe nothrow @nogcValidate a connection config, returning defaults if invalid.TcpListenerConfig validated(TcpListenerConfig config) pure @safe nothrow @nogcValidate a listener config, returning defaults if invalid.const(char) * copyStringz(scope const(char)[] source, scope char[] buffer) @trusted nothrowCopy a D string slice to a null-terminated C string buffer.const(char) * portToString(ushort port, scope char[] buffer) @trusted nothrowConvert a port number to a null-terminated string.int setTcpNoDelay(SOCKET sock) @trusted nothrow @nogcDisable Nagle's algorithm on a socket.void applySocketBufferSizes(SOCKET sock, const ref TcpConnectionConfig config) @trusted nothrowApply socket buffer size options from config.void applyKeepAlive(SOCKET sock, const ref TcpConnectionConfig config) @trusted nothrowEnable TCP keepalive with configured intervals using WSAIoctl.bool wouldBlock() @trusted nothrowCheck if the last Winsock error indicates the operation would block.int mapWsaError(int wsaError) pure @safe nothrow @nogcMap Winsock error code to POSIX-style errno.ushort queryLocalPort(SOCKET sock) @trusted nothrowQuery the local port number for a bound socket.AddrinfoRange addrinfoRange(addrinfo * first) pure @safe nothrow @nogcCreate a range over an addrinfo linked list.Variables 4
SOMAXCONN = 0x7fffffffMaximum listen backlog (not in druntime's winsock2).
TCP_READ_BUFFER_SIZE = 8192Size of the internal read/write buffer for overlapped I/O.
ACCEPT_ADDR_LEN = SOCKADDR_STORAGE.sizeof + 16Size of address buffer for AcceptEx (sockaddr_storage + 16 bytes padding).
ACCEPT_BUFFER_SIZE = ACCEPT_ADDR_LEN * 2Total buffer size for AcceptEx (local + remote addresses).