<!--
{
  "availability" : [

  ],
  "documentType" : "symbol",
  "framework" : "Event",
  "identifier" : "/documentation/Event/Socket",
  "metadataVersion" : "0.1.0",
  "role" : "Class",
  "symbol" : {
    "kind" : "Class",
    "modules" : [
      "Event"
    ],
    "preciseIdentifier" : "s:5Event6SocketC"
  },
  "title" : "Socket"
}
-->

# Socket

An async non-blocking TCP socket backed by libevent.

```
final class Socket
```

## Overview

`Socket` wraps a POSIX file descriptor configured for non-blocking I/O and drives
it through an [`EventLoop`](/documentation/Event/EventLoop) so that [`read(maxBytes:)`](/documentation/Event/Socket/read(maxBytes:)) and [`write(_:)`](/documentation/Event/Socket/write(_:)) resume
their callers only when the kernel indicates data readiness. The async surface
(`async throws` methods) composes naturally with Swift structured concurrency;
the underlying mechanism is libevent callbacks bridging to `CheckedContinuation`s.

`Socket` covers three roles:

- **TCP client** — acquired via ``doc://Event/documentation/Event/Socket/connect(to:port:loop:)`` or
  ``doc://Event/documentation/Event/Socket/connect(to:loop:)``.
- **Accepted server connection** — delivered by ``doc://Event/documentation/Event/ServerSocket/accept()`` or the
  ``doc://Event/documentation/Event/ServerSocket/connections`` stream.
- **Wrapping an existing descriptor** — not exposed publicly (the initializer is
  `internal`), but used by the library itself when an external fd must be adopted.

Server-listener construction lives on [`listen(port:backlog:loop:)`](/documentation/Event/Socket/listen(port:backlog:loop:)) and
[`listen(on:backlog:loop:)`](/documentation/Event/Socket/listen(on:backlog:loop:)), which return a [`ServerSocket`](/documentation/Event/ServerSocket) — not a `Socket`.

### Resource ownership

A `Socket` owns its descriptor by default: `deinit` calls `close(2)`. The
`ownsDescriptor` initializer flag exists so callers can wrap an externally-owned
fd without double-close risk; this path is internal today. The single-ownership
invariant is a constitution Principle II concern — see [Production Considerations](/documentation/Event/ProductionConsiderations).

### Concurrency

Marked `@unchecked Sendable` to permit handoff of ownership across task boundaries.
Concurrent I/O on the same `Socket` from multiple tasks (e.g. `read` from one task
while `write` from another) is **undefined behavior**: the libevent callback state
is not synchronized, and `fd` is mutated unconditionally in `deinit`. Use
structured concurrency scopes to bound ownership. See [Production Considerations](/documentation/Event/ProductionConsiderations)
“Concurrency Model” for the honest description.