0
# Socket Interfaces
1
2
Ktor Network provides a comprehensive hierarchy of socket interfaces that separate concerns and enable flexible socket implementations. The interfaces follow capability-based design, allowing sockets to implement only the functionality they support.
3
4
## Base Socket Interface
5
6
### ASocket - Foundation Interface
7
8
```kotlin { .api }
9
interface ASocket : Closeable, DisposableHandle {
10
val socketContext: Job
11
val isClosed: Boolean
12
suspend fun awaitClosed()
13
}
14
```
15
16
The base interface for all async sockets, providing lifecycle management and coroutine integration.
17
18
**Properties:**
19
- `socketContext: Job` - Coroutine job managing the socket's lifecycle
20
- `isClosed: Boolean` - Current closed state of the socket
21
22
**Methods:**
23
- `suspend fun awaitClosed()` - Suspends until the socket is closed
24
- `close()` - Inherited from Closeable, closes the socket immediately
25
- `dispose()` - Inherited from DisposableHandle, disposes resources
26
27
## Capability Interfaces
28
29
### Socket Address Capabilities
30
31
```kotlin { .api }
32
interface ABoundSocket {
33
val localAddress: SocketAddress
34
}
35
36
interface AConnectedSocket {
37
val remoteAddress: SocketAddress
38
}
39
```
40
41
Interfaces providing address information for sockets.
42
43
**ABoundSocket:**
44
- `localAddress: SocketAddress` - The local address the socket is bound to
45
46
**AConnectedSocket:**
47
- `remoteAddress: SocketAddress` - The remote address the socket is connected to
48
49
### I/O Capability Interfaces
50
51
```kotlin { .api }
52
interface AReadable {
53
fun attachForReading(channel: ByteChannel): WriterJob
54
fun openReadChannel(): ByteReadChannel
55
}
56
57
interface AWritable {
58
fun attachForWriting(channel: ByteChannel): ReaderJob
59
fun openWriteChannel(autoFlush: Boolean = false): ByteWriteChannel
60
}
61
62
interface ReadWriteSocket : ASocket, AReadable, AWritable
63
```
64
65
Interfaces providing I/O capabilities for sockets.
66
67
**AReadable:**
68
- `attachForReading(channel: ByteChannel): WriterJob` - Attaches a channel for reading data
69
- `openReadChannel(): ByteReadChannel` - Opens a dedicated read channel
70
71
**AWritable:**
72
- `attachForWriting(channel: ByteChannel): ReaderJob` - Attaches a channel for writing data
73
- `openWriteChannel(autoFlush: Boolean = false): ByteWriteChannel` - Opens a dedicated write channel
74
75
### Connection Acceptance
76
77
```kotlin { .api }
78
interface Acceptable<out S : ASocket> {
79
suspend fun accept(): S
80
}
81
```
82
83
Interface for sockets that can accept incoming connections.
84
85
**Methods:**
86
- `suspend fun accept(): S` - Suspends until a new connection is accepted and returns the client socket
87
88
## Concrete Socket Types
89
90
### TCP Socket
91
92
```kotlin { .api }
93
interface Socket : ReadWriteSocket, ABoundSocket, AConnectedSocket, CoroutineScope
94
```
95
96
Represents a connected TCP socket with full bidirectional I/O capabilities.
97
98
**Capabilities:**
99
- Read and write data streams
100
- Access to both local and remote addresses
101
- Coroutine-based lifecycle management
102
103
### TCP Server Socket
104
105
```kotlin { .api }
106
interface ServerSocket : ASocket, ABoundSocket, Acceptable<Socket>
107
```
108
109
Represents a TCP server socket that listens for and accepts incoming connections.
110
111
**Capabilities:**
112
- Accept incoming TCP connections
113
- Access to bound local address
114
- Coroutine-based lifecycle management
115
116
## Usage Examples
117
118
### Working with TCP Sockets
119
120
```kotlin
121
import io.ktor.network.sockets.*
122
import io.ktor.network.selector.*
123
import io.ktor.utils.io.*
124
125
suspend fun handleTcpConnection() {
126
val selectorManager = SelectorManager()
127
val socket = aSocket(selectorManager)
128
.tcp()
129
.connect(InetSocketAddress("example.com", 80))
130
131
// Socket implements all capability interfaces
132
println("Connected to: ${socket.remoteAddress}")
133
println("Local address: ${socket.localAddress}")
134
135
// Use I/O capabilities
136
val input: ByteReadChannel = socket.openReadChannel()
137
val output: ByteWriteChannel = socket.openWriteChannel(autoFlush = true)
138
139
// Write HTTP request
140
output.writeStringUtf8("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
141
142
// Read response
143
val response = input.readUTF8Line()
144
println("Response: $response")
145
146
socket.close()
147
selectorManager.close()
148
}
149
```
150
151
### TCP Server with Connection Handling
152
153
```kotlin
154
suspend fun runTcpServer() {
155
val selectorManager = SelectorManager()
156
val serverSocket = aSocket(selectorManager)
157
.tcp()
158
.bind(InetSocketAddress("localhost", 8080))
159
160
println("Server bound to: ${serverSocket.localAddress}")
161
println("Server port: ${serverSocket.port}")
162
163
while (!serverSocket.isClosed) {
164
try {
165
// Accept new connection
166
val clientSocket = serverSocket.accept()
167
168
// Handle each client in a separate coroutine
169
launch {
170
handleClient(clientSocket)
171
}
172
} catch (e: Exception) {
173
println("Error accepting connection: ${e.message}")
174
break
175
}
176
}
177
178
serverSocket.close()
179
selectorManager.close()
180
}
181
182
suspend fun handleClient(clientSocket: Socket) {
183
try {
184
println("Client connected from: ${clientSocket.remoteAddress}")
185
186
val input = clientSocket.openReadChannel()
187
val output = clientSocket.openWriteChannel(autoFlush = true)
188
189
// Echo server implementation
190
while (!clientSocket.isClosed) {
191
val line = input.readUTF8Line() ?: break
192
output.writeStringUtf8("Echo: $line\n")
193
}
194
} catch (e: Exception) {
195
println("Error handling client: ${e.message}")
196
} finally {
197
clientSocket.close()
198
}
199
}
200
```
201
202
### Using Channel Attachment
203
204
```kotlin
205
suspend fun useChannelAttachment() {
206
val selectorManager = SelectorManager()
207
val socket = aSocket(selectorManager)
208
.tcp()
209
.connect(InetSocketAddress("example.com", 80))
210
211
// Create a custom byte channel for processing
212
val customChannel = ByteChannel()
213
214
// Attach the custom channel for reading from socket
215
val writerJob = socket.attachForReading(customChannel)
216
217
// Process data from the custom channel
218
launch {
219
while (!customChannel.isClosedForRead) {
220
val line = customChannel.readUTF8Line() ?: break
221
println("Processed: $line")
222
}
223
}
224
225
// Wait for some data to be read
226
delay(5000)
227
228
// Clean up
229
writerJob.cancel()
230
socket.close()
231
selectorManager.close()
232
}
233
```
234
235
### Socket State Management
236
237
```kotlin
238
suspend fun manageSocketLifecycle() {
239
val selectorManager = SelectorManager()
240
val socket = aSocket(selectorManager)
241
.tcp()
242
.connect(InetSocketAddress("example.com", 80))
243
244
// Monitor socket state
245
println("Socket opened, isClosed: ${socket.isClosed}")
246
247
// Setup a coroutine to monitor when socket closes
248
launch {
249
socket.awaitClosed()
250
println("Socket has been closed")
251
}
252
253
// Use socket for some operations
254
val output = socket.openWriteChannel()
255
output.writeStringUtf8("Hello World")
256
257
// Explicitly close the socket
258
socket.close()
259
260
// Verify closure
261
println("After close(), isClosed: ${socket.isClosed}")
262
263
selectorManager.close()
264
}
265
```
266
267
## Type Definitions
268
269
### Required Import Statements
270
271
```kotlin
272
import io.ktor.network.sockets.*
273
import io.ktor.utils.io.*
274
import kotlinx.coroutines.*
275
import kotlinx.coroutines.channels.*
276
```
277
278
### Related Types
279
280
- `SocketAddress`, `InetSocketAddress` - See [Address Types](./address-types.md)
281
- `ByteReadChannel`, `ByteWriteChannel`, `ByteChannel` - From kotlinx-io
282
- `Job`, `WriterJob`, `ReaderJob` - From kotlinx-coroutines
283
- `SelectorManager` - See [Selectors](./selectors.md)
284
- `BoundDatagramSocket`, `ConnectedDatagramSocket` - See [Datagram Sockets](./datagram-sockets.md)
285
286
### Exception Types
287
288
```kotlin { .api }
289
class SocketTimeoutException(message: String) : Exception
290
```
291
292
Common exceptions thrown by socket operations.