or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

address-types.mddatagram-sockets.mdindex.mdselectors.mdsocket-builders.mdsocket-interfaces.mdsocket-options.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

Ktor Network provides a comprehensive set of utility functions, extensions, and helper classes that simplify common socket operations and provide convenient abstractions for networking tasks.

3

4

## Socket Extension Functions

5

6

### Lifecycle Extensions

7

8

```kotlin { .api }

9

val ASocket.isClosed: Boolean

10

11

suspend fun ASocket.awaitClosed()

12

```

13

14

Extensions for monitoring socket lifecycle state.

15

16

**Properties:**

17

- `isClosed: Boolean` - Returns true if the socket has been closed

18

19

**Methods:**

20

- `suspend fun awaitClosed()` - Suspends the current coroutine until the socket is closed

21

22

### I/O Channel Extensions

23

24

```kotlin { .api }

25

fun AReadable.openReadChannel(): ByteReadChannel

26

27

fun AWritable.openWriteChannel(autoFlush: Boolean = false): ByteWriteChannel

28

```

29

30

Extensions for opening I/O channels on readable and writable sockets.

31

32

**AReadable Extensions:**

33

- `openReadChannel(): ByteReadChannel` - Opens a dedicated read channel for receiving data

34

35

**AWritable Extensions:**

36

- `openWriteChannel(autoFlush: Boolean = false): ByteWriteChannel` - Opens a dedicated write channel for sending data

37

- `autoFlush: Boolean` - Whether to automatically flush written data (default: false)

38

39

### Connection Utility

40

41

```kotlin { .api }

42

fun Socket.connection(): Connection

43

```

44

45

Creates a convenient Connection wrapper for TCP sockets.

46

47

**Returns:** `Connection` - A wrapper containing both input and output channels

48

49

### Server Socket Extensions

50

51

```kotlin { .api }

52

val ServerSocket.port: Int

53

```

54

55

Extension property to get the port number from a server socket.

56

57

**Returns:** `Int` - The port number the server socket is bound to

58

59

## Connection Wrapper Class

60

61

### Connection Class

62

63

```kotlin { .api }

64

class Connection(

65

val socket: Socket,

66

val input: ByteReadChannel,

67

val output: ByteWriteChannel

68

) : Closeable {

69

override fun close()

70

}

71

```

72

73

Convenience class that combines a socket with its I/O channels for easier handling.

74

75

**Properties:**

76

- `socket: Socket` - The underlying TCP socket

77

- `input: ByteReadChannel` - Read channel for receiving data

78

- `output: ByteWriteChannel` - Write channel for sending data

79

80

**Methods:**

81

- `close()` - Closes the connection and all associated resources

82

83

## Type of Service (QoS)

84

85

### TypeOfService Value Class

86

87

```kotlin { .api }

88

@JvmInline

89

value class TypeOfService(val value: UByte) {

90

constructor(value: Int) : this(value.toUByte())

91

92

val intValue: Int get() = value.toInt()

93

94

companion object {

95

val UNDEFINED: TypeOfService

96

val IPTOS_LOWCOST: TypeOfService

97

val IPTOS_RELIABILITY: TypeOfService

98

val IPTOS_THROUGHPUT: TypeOfService

99

val IPTOS_LOWDELAY: TypeOfService

100

}

101

}

102

```

103

104

Inline value class for IP Type of Service (ToS) field configuration.

105

106

**Properties:**

107

- `value: UByte` - The underlying byte value for the ToS field

108

- `intValue: Int` - Computed property returning the ToS value as an integer

109

110

**Constructors:**

111

- `TypeOfService(value: UByte)` - Primary constructor taking a UByte value

112

- `TypeOfService(value: Int)` - Secondary constructor taking Int and converting to UByte

113

114

**Companion Constants:**

115

- `UNDEFINED` - Default/undefined ToS value

116

- `IPTOS_LOWCOST` - Optimize for low cost

117

- `IPTOS_RELIABILITY` - Optimize for reliability

118

- `IPTOS_THROUGHPUT` - Optimize for high throughput

119

- `IPTOS_LOWDELAY` - Optimize for low latency

120

121

## Usage Examples

122

123

### Basic Socket Lifecycle Management

124

125

```kotlin

126

import io.ktor.network.sockets.*

127

import io.ktor.network.selector.*

128

129

suspend fun monitorSocketLifecycle() {

130

val selectorManager = SelectorManager()

131

val socket = aSocket(selectorManager)

132

.tcp()

133

.connect(InetSocketAddress("example.com", 80))

134

135

println("Socket connected: ${!socket.isClosed}")

136

137

// Set up monitoring coroutine

138

launch {

139

socket.awaitClosed()

140

println("Socket has been closed")

141

}

142

143

// Use socket...

144

delay(1000)

145

146

// Close and verify

147

socket.close()

148

println("After close: isClosed = ${socket.isClosed}")

149

150

selectorManager.close()

151

}

152

```

153

154

### Using Connection Wrapper

155

156

```kotlin

157

suspend fun useConnectionWrapper() {

158

val selectorManager = SelectorManager()

159

val socket = aSocket(selectorManager)

160

.tcp()

161

.connect(InetSocketAddress("httpbin.org", 80))

162

163

// Create connection wrapper

164

val connection = socket.connection()

165

166

println("Connection established:")

167

println("Socket: ${connection.socket.remoteAddress}")

168

169

// Send HTTP request

170

connection.output.writeStringUtf8("GET /get HTTP/1.1\r\n")

171

connection.output.writeStringUtf8("Host: httpbin.org\r\n")

172

connection.output.writeStringUtf8("Connection: close\r\n\r\n")

173

connection.output.flush()

174

175

// Read response

176

val response = connection.input.readUTF8Line()

177

println("Response: $response")

178

179

// Connection.close() handles all cleanup

180

connection.close()

181

selectorManager.close()

182

}

183

```

184

185

### Server Socket Port Utilities

186

187

```kotlin

188

suspend fun serverPortUtilities() {

189

val selectorManager = SelectorManager()

190

191

// Server with dynamic port assignment

192

val server = aSocket(selectorManager)

193

.tcp()

194

.bind(InetSocketAddress("localhost", 0)) // Port 0 = any available

195

196

// Get the assigned port

197

val assignedPort = server.port

198

println("Server listening on port: $assignedPort")

199

println("Full address: ${server.localAddress}")

200

201

// Another way to get port from address

202

val addressPort = (server.localAddress as InetSocketAddress).port

203

println("Port from address: $addressPort")

204

205

server.close()

206

selectorManager.close()

207

}

208

```

209

210

### Advanced I/O Channel Usage

211

212

```kotlin

213

import io.ktor.utils.io.*

214

215

suspend fun advancedChannelUsage() {

216

val selectorManager = SelectorManager()

217

val socket = aSocket(selectorManager)

218

.tcp()

219

.connect(InetSocketAddress("example.com", 80))

220

221

// Open channels with specific settings

222

val input = socket.openReadChannel()

223

val output = socket.openWriteChannel(autoFlush = true) // Auto-flush enabled

224

225

// Send data

226

output.writeStringUtf8("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")

227

228

// Read response headers

229

val headers = mutableListOf<String>()

230

while (true) {

231

val line = input.readUTF8Line() ?: break

232

if (line.isEmpty()) break // End of headers

233

headers.add(line)

234

}

235

236

println("Response headers:")

237

headers.forEach { println(it) }

238

239

socket.close()

240

selectorManager.close()

241

}

242

```

243

244

### Type of Service Configuration

245

246

```kotlin

247

// Note: ToS configuration would typically be applied during socket creation

248

// This example shows the ToS value usage pattern

249

250

fun demonstrateTypeOfService() {

251

// Different QoS requirements

252

val lowLatencyToS = TypeOfService.IPTOS_LOWDELAY

253

val highThroughputToS = TypeOfService.IPTOS_THROUGHPUT

254

val reliableToS = TypeOfService.IPTOS_RELIABILITY

255

val lowCostToS = TypeOfService.IPTOS_LOWCOST

256

257

println("ToS values:")

258

println("Low Latency: ${lowLatencyToS.intValue}")

259

println("High Throughput: ${highThroughputToS.intValue}")

260

println("Reliability: ${reliableToS.intValue}")

261

println("Low Cost: ${lowCostToS.intValue}")

262

263

// Custom ToS value

264

val customToS = TypeOfService(0x18) // Custom value

265

println("Custom ToS: ${customToS.intValue}")

266

}

267

```

268

269

### Error-Resilient Connection Management

270

271

```kotlin

272

suspend fun resilientConnectionManagement() {

273

val selectorManager = SelectorManager()

274

275

try {

276

val socket = aSocket(selectorManager)

277

.tcp()

278

.configure {

279

socketTimeout = 10000 // 10 second timeout

280

}

281

.connect(InetSocketAddress("example.com", 80))

282

283

// Monitor connection state

284

if (!socket.isClosed) {

285

val connection = socket.connection()

286

287

try {

288

// Perform operations

289

connection.output.writeStringUtf8("Hello\n")

290

connection.output.flush()

291

292

// Check if still connected before reading

293

if (!connection.socket.isClosed) {

294

val response = connection.input.readUTF8Line()

295

println("Received: $response")

296

}

297

298

} catch (e: Exception) {

299

println("Connection error: ${e.message}")

300

} finally {

301

connection.close()

302

}

303

}

304

305

} catch (e: Exception) {

306

println("Socket creation failed: ${e.message}")

307

} finally {

308

selectorManager.close()

309

}

310

}

311

```

312

313

### Bulk Connection Operations

314

315

```kotlin

316

suspend fun bulkConnectionOperations() {

317

val selectorManager = SelectorManager()

318

val connections = mutableListOf<Connection>()

319

320

try {

321

// Create multiple connections

322

val addresses = listOf(

323

InetSocketAddress("httpbin.org", 80),

324

InetSocketAddress("example.com", 80),

325

InetSocketAddress("google.com", 80)

326

)

327

328

addresses.forEach { address ->

329

try {

330

val socket = aSocket(selectorManager)

331

.tcp()

332

.connect(address)

333

334

val connection = socket.connection()

335

connections.add(connection)

336

337

println("Connected to ${address}")

338

} catch (e: Exception) {

339

println("Failed to connect to ${address}: ${e.message}")

340

}

341

}

342

343

// Perform operations on all connections

344

connections.forEach { connection ->

345

launch {

346

try {

347

connection.output.writeStringUtf8("GET / HTTP/1.1\r\nHost: ${(connection.socket.remoteAddress as InetSocketAddress).hostname}\r\n\r\n")

348

connection.output.flush()

349

350

val response = connection.input.readUTF8Line()

351

println("Response from ${connection.socket.remoteAddress}: $response")

352

} catch (e: Exception) {

353

println("Operation failed for ${connection.socket.remoteAddress}: ${e.message}")

354

}

355

}

356

}

357

358

// Wait for operations to complete

359

delay(5000)

360

361

} finally {

362

// Clean up all connections

363

connections.forEach { connection ->

364

try {

365

connection.close()

366

} catch (e: Exception) {

367

println("Error closing connection: ${e.message}")

368

}

369

}

370

selectorManager.close()

371

}

372

}

373

```

374

375

### Connection Pooling Utility

376

377

```kotlin

378

class ConnectionPool(private val selectorManager: SelectorManager) {

379

private val connections = mutableMapOf<SocketAddress, MutableList<Connection>>()

380

381

suspend fun getConnection(address: SocketAddress): Connection {

382

val pool = connections.getOrPut(address) { mutableListOf() }

383

384

return if (pool.isNotEmpty()) {

385

val connection = pool.removeAt(0)

386

if (!connection.socket.isClosed) {

387

connection

388

} else {

389

createNewConnection(address)

390

}

391

} else {

392

createNewConnection(address)

393

}

394

}

395

396

private suspend fun createNewConnection(address: SocketAddress): Connection {

397

val socket = aSocket(selectorManager)

398

.tcp()

399

.connect(address)

400

401

return socket.connection()

402

}

403

404

fun returnConnection(connection: Connection) {

405

if (!connection.socket.isClosed) {

406

val address = connection.socket.remoteAddress

407

val pool = connections.getOrPut(address) { mutableListOf() }

408

pool.add(connection)

409

} else {

410

connection.close()

411

}

412

}

413

414

fun closeAll() {

415

connections.values.flatten().forEach { connection ->

416

try {

417

connection.close()

418

} catch (e: Exception) {

419

println("Error closing pooled connection: ${e.message}")

420

}

421

}

422

connections.clear()

423

}

424

}

425

426

suspend fun useConnectionPool() {

427

val selectorManager = SelectorManager()

428

val pool = ConnectionPool(selectorManager)

429

430

try {

431

val address = InetSocketAddress("httpbin.org", 80)

432

433

// Get connection from pool

434

val connection1 = pool.getConnection(address)

435

println("Got connection: ${connection1.socket.remoteAddress}")

436

437

// Use connection...

438

connection1.output.writeStringUtf8("GET /get HTTP/1.1\r\nHost: httpbin.org\r\n\r\n")

439

440

// Return to pool for reuse

441

pool.returnConnection(connection1)

442

443

// Get another connection (might be the same one)

444

val connection2 = pool.getConnection(address)

445

println("Got connection: ${connection2.socket.remoteAddress}")

446

447

pool.returnConnection(connection2)

448

449

} finally {

450

pool.closeAll()

451

selectorManager.close()

452

}

453

}

454

```

455

456

## Constants and Limits

457

458

### Maximum Values

459

460

```kotlin { .api }

461

const val MAX_DATAGRAM_SIZE = 65535

462

```

463

464

Maximum size for UDP datagrams (65535 bytes).

465

466

## Type Definitions

467

468

### Required Import Statements

469

470

```kotlin

471

import io.ktor.network.sockets.*

472

import io.ktor.utils.io.*

473

import kotlinx.coroutines.*

474

```

475

476

### Related Types

477

478

- Extends all socket interfaces - See [Socket Interfaces](./socket-interfaces.md)

479

- Used with socket builders - See [Socket Builders](./socket-builders.md)

480

- Enhances datagram operations - See [Datagram Sockets](./datagram-sockets.md)

481

- Works with all address types - See [Address Types](./address-types.md)

482

- `ByteReadChannel`, `ByteWriteChannel` - From kotlinx-io

483

- `Closeable` - From Kotlin standard library

484

485

### Exception Types

486

487

Utility functions may throw the same exceptions as their underlying socket operations. Always handle exceptions appropriately in production code.