or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdasync-io.mdauth.mddistributed.mddns.mdemail.mdhttp.mdindex.mdlogging.mdprotocols.mdssh.mdtesting.md

protocols.mddocs/

0

# Network Protocols

1

2

Implementations of various network protocols including FTP, IRC, XMPP, AMP (Asynchronous Messaging Protocol), and utilities for building custom protocols. Twisted provides a rich ecosystem of protocol implementations.

3

4

## Capabilities

5

6

### Basic Protocol Building Blocks

7

8

Fundamental protocol classes for building line-oriented and length-prefixed protocols.

9

10

```python { .api }

11

class basic.LineReceiver:

12

"""

13

Protocol that receives data line by line.

14

15

Attributes:

16

- delimiter: Line delimiter (default: b'\\r\\n')

17

- MAX_LENGTH: Maximum line length

18

- clearLineBuffer: Whether to clear buffer on line length exceeded

19

"""

20

delimiter = b'\r\n'

21

MAX_LENGTH = 16384

22

clearLineBuffer = False

23

24

def lineReceived(self, line):

25

"""

26

Called when a complete line is received.

27

28

Args:

29

line (bytes): Received line (without delimiter)

30

"""

31

32

def lineLengthExceeded(self, line):

33

"""

34

Called when line exceeds MAX_LENGTH.

35

36

Args:

37

line (bytes): Partial line data

38

"""

39

40

def sendLine(self, line):

41

"""

42

Send a line with delimiter.

43

44

Args:

45

line (bytes): Line to send

46

"""

47

48

def setLineMode(self, extra=b''):

49

"""

50

Switch to line-based receiving mode.

51

52

Args:

53

extra (bytes): Extra data to process

54

"""

55

56

def setRawMode(self):

57

"""Switch to raw data receiving mode."""

58

59

class basic.IntNStringReceiver:

60

"""

61

Protocol that receives length-prefixed strings.

62

63

Attributes:

64

- structFormat: Struct format for length field

65

- prefixLength: Length of length prefix

66

- MAX_LENGTH: Maximum string length

67

"""

68

structFormat = '!I' # 32-bit big-endian unsigned int

69

prefixLength = 4

70

MAX_LENGTH = 99999999

71

72

def stringReceived(self, string):

73

"""

74

Called when a complete string is received.

75

76

Args:

77

string (bytes): Received string

78

"""

79

80

def lengthLimitExceeded(self, length):

81

"""

82

Called when string length exceeds MAX_LENGTH.

83

84

Args:

85

length (int): Attempted string length

86

"""

87

88

def sendString(self, string):

89

"""

90

Send a length-prefixed string.

91

92

Args:

93

string (bytes): String to send

94

"""

95

96

class basic.Int32StringReceiver(basic.IntNStringReceiver):

97

"""32-bit length-prefixed string receiver."""

98

structFormat = '!I'

99

prefixLength = 4

100

101

class basic.Int16StringReceiver(basic.IntNStringReceiver):

102

"""16-bit length-prefixed string receiver."""

103

structFormat = '!H'

104

prefixLength = 2

105

106

class basic.Int8StringReceiver(basic.IntNStringReceiver):

107

"""8-bit length-prefixed string receiver."""

108

structFormat = '!B'

109

prefixLength = 1

110

111

class basic.NetstringReceiver:

112

"""

113

Protocol that receives netstring-encoded data.

114

115

Netstring format: <length>:<data>,

116

"""

117

MAX_LENGTH = 99999999

118

119

def stringReceived(self, string):

120

"""

121

Called when a complete netstring is received.

122

123

Args:

124

string (bytes): Received string data

125

"""

126

127

def lengthLimitExceeded(self, length):

128

"""

129

Called when netstring length exceeds MAX_LENGTH.

130

131

Args:

132

length (int): Attempted string length

133

"""

134

135

def sendString(self, string):

136

"""

137

Send a netstring.

138

139

Args:

140

string (bytes): String to send

141

"""

142

143

class basic.StatefulStringProtocol:

144

"""

145

Protocol with multiple states for complex parsing.

146

147

States are methods named 'proto_<STATE>' that return next state.

148

"""

149

def proto_init(self):

150

"""

151

Initial protocol state.

152

153

Returns:

154

str: Next state name

155

"""

156

```

157

158

**Basic Protocol Usage Example**:

159

160

```python

161

from twisted.protocols import basic

162

from twisted.internet import protocol, reactor, endpoints

163

164

class ChatProtocol(basic.LineReceiver):

165

delimiter = b'\n'

166

167

def connectionMade(self):

168

self.sendLine(b"Welcome to chat server!")

169

self.factory.clients.append(self)

170

171

def connectionLost(self, reason):

172

if self in self.factory.clients:

173

self.factory.clients.remove(self)

174

175

def lineReceived(self, line):

176

message = f"User says: {line.decode()}"

177

# Broadcast to all clients

178

for client in self.factory.clients:

179

if client != self:

180

client.sendLine(message.encode())

181

182

class ChatFactory(protocol.ServerFactory):

183

def __init__(self):

184

self.clients = []

185

186

def buildProtocol(self, addr):

187

protocol = ChatProtocol()

188

protocol.factory = self

189

return protocol

190

191

# Start server

192

endpoint = endpoints.TCP4ServerEndpoint(reactor, 8080)

193

endpoint.listen(ChatFactory())

194

reactor.run()

195

```

196

197

### Asynchronous Messaging Protocol (AMP)

198

199

High-level RPC protocol with structured commands and responses.

200

201

```python { .api }

202

class amp.AMP:

203

"""

204

Asynchronous Messaging Protocol implementation.

205

206

Provides structured command/response messaging over TCP.

207

"""

208

def __init__(self, boxReceiver=None, locator=None):

209

"""

210

Args:

211

boxReceiver: Custom box receiver

212

locator: Command locator

213

"""

214

215

def callRemote(self, command, **kwargs):

216

"""

217

Call remote command.

218

219

Args:

220

command: AMP command class

221

**kwargs: Command arguments

222

223

Returns:

224

Deferred: Response from remote

225

"""

226

227

def callRemoteString(self, commandName, **kwargs):

228

"""

229

Call remote command by name.

230

231

Args:

232

commandName (str): Command name

233

**kwargs: Command arguments

234

235

Returns:

236

Deferred: Response from remote

237

"""

238

239

class amp.Command:

240

"""

241

Base class for AMP commands.

242

243

Attributes:

244

- commandName: Command name (bytes)

245

- arguments: List of command arguments

246

- response: List of response arguments

247

- errors: Dict of error mappings

248

- requiresAnswer: Whether command expects response

249

"""

250

commandName = None

251

arguments = []

252

response = []

253

errors = {}

254

requiresAnswer = True

255

256

@classmethod

257

def makeArguments(cls, objects, proto):

258

"""

259

Serialize command arguments.

260

261

Args:

262

objects (dict): Argument values

263

proto: Protocol instance

264

265

Returns:

266

dict: Serialized arguments

267

"""

268

269

@classmethod

270

def parseResponse(cls, strings, proto):

271

"""

272

Parse command response.

273

274

Args:

275

strings (dict): Response data

276

proto: Protocol instance

277

278

Returns:

279

dict: Parsed response

280

"""

281

282

# AMP argument types

283

class amp.Argument:

284

"""Base class for AMP argument types."""

285

286

def toString(self, inObject):

287

"""

288

Serialize argument to string.

289

290

Args:

291

inObject: Python object

292

293

Returns:

294

bytes: Serialized form

295

"""

296

297

def fromString(self, inString):

298

"""

299

Deserialize argument from string.

300

301

Args:

302

inString (bytes): Serialized form

303

304

Returns:

305

Python object

306

"""

307

308

class amp.Integer(amp.Argument):

309

"""Integer argument type."""

310

311

class amp.String(amp.Argument):

312

"""String argument type."""

313

314

class amp.Unicode(amp.Argument):

315

"""Unicode string argument type."""

316

317

class amp.Boolean(amp.Argument):

318

"""Boolean argument type."""

319

320

class amp.Float(amp.Argument):

321

"""Float argument type."""

322

323

class amp.Decimal(amp.Argument):

324

"""Decimal argument type."""

325

326

class amp.DateTime(amp.Argument):

327

"""DateTime argument type."""

328

329

class amp.ListOf(amp.Argument):

330

"""List argument type."""

331

def __init__(self, elementType):

332

"""

333

Args:

334

elementType: Type of list elements

335

"""

336

```

337

338

**AMP Usage Example**:

339

340

```python

341

from twisted.protocols import amp

342

from twisted.internet import reactor, defer

343

344

# Define commands

345

class Sum(amp.Command):

346

commandName = b'sum'

347

arguments = [

348

(b'a', amp.Integer()),

349

(b'b', amp.Integer()),

350

]

351

response = [

352

(b'result', amp.Integer()),

353

]

354

355

class Greeting(amp.Command):

356

commandName = b'greeting'

357

arguments = [

358

(b'name', amp.Unicode()),

359

]

360

response = [

361

(b'message', amp.Unicode()),

362

]

363

364

# Server implementation

365

class MathServer(amp.AMP):

366

def sum(self, a, b):

367

return {'result': a + b}

368

369

def greeting(self, name):

370

return {'message': f'Hello, {name}!'}

371

372

# Client usage

373

class MathClient(amp.AMP):

374

def connectionMade(self):

375

amp.AMP.connectionMade(self)

376

377

# Call remote commands

378

d1 = self.callRemote(Sum, a=5, b=3)

379

d1.addCallback(lambda result: print(f"Sum: {result['result']}"))

380

381

d2 = self.callRemote(Greeting, name="Alice")

382

d2.addCallback(lambda result: print(f"Greeting: {result['message']}"))

383

```

384

385

### FTP Protocol

386

387

File Transfer Protocol client and server implementations.

388

389

```python { .api }

390

class ftp.FTP:

391

"""

392

FTP server protocol implementation.

393

394

Attributes:

395

- shell: Avatar object providing file system interface

396

- workingDirectory: Current working directory

397

"""

398

shell = None

399

workingDirectory = None

400

401

def ftp_USER(self, params):

402

"""Handle USER command."""

403

404

def ftp_PASS(self, params):

405

"""Handle PASS command."""

406

407

def ftp_LIST(self, params):

408

"""Handle LIST command."""

409

410

def ftp_RETR(self, params):

411

"""Handle RETR command."""

412

413

def ftp_STOR(self, params):

414

"""Handle STOR command."""

415

416

class ftp.FTPFactory:

417

"""

418

FTP server factory.

419

"""

420

def __init__(self):

421

self.timeOut = 600 # Session timeout

422

self.welcomeMessage = "Welcome to FTP server"

423

424

class ftp.FTPClient:

425

"""

426

FTP client protocol implementation.

427

"""

428

def __init__(self, username='anonymous', password='twisted@twistedmatrix.com', passive=1):

429

"""

430

Args:

431

username (str): FTP username

432

password (str): FTP password

433

passive (bool): Use passive mode

434

"""

435

436

def retrieveFile(self, filename, callback, offset=0):

437

"""

438

Retrieve file from server.

439

440

Args:

441

filename (str): Remote filename

442

callback: Function to receive file data

443

offset (int): Start offset

444

445

Returns:

446

Deferred: Completion indicator

447

"""

448

449

def storeFile(self, filename, file, offset=0):

450

"""

451

Store file on server.

452

453

Args:

454

filename (str): Remote filename

455

file: File-like object to upload

456

offset (int): Start offset

457

458

Returns:

459

Deferred: Completion indicator

460

"""

461

462

def list(self, path, callback):

463

"""

464

List directory contents.

465

466

Args:

467

path (str): Directory path

468

callback: Function to receive listing data

469

470

Returns:

471

Deferred: Completion indicator

472

"""

473

474

def makeDirectory(self, path):

475

"""

476

Create directory.

477

478

Args:

479

path (str): Directory path

480

481

Returns:

482

Deferred: Completion indicator

483

"""

484

485

def removeFile(self, path):

486

"""

487

Remove file.

488

489

Args:

490

path (str): File path

491

492

Returns:

493

Deferred: Completion indicator

494

"""

495

496

class ftp.FTPClientBasic:

497

"""

498

Basic FTP client with simple interface.

499

"""

500

def __init__(self, username='anonymous', password='twisted@twistedmatrix.com'):

501

"""

502

Args:

503

username (str): FTP username

504

password (str): FTP password

505

"""

506

507

def connectTo(self, host, port=21):

508

"""

509

Connect to FTP server.

510

511

Args:

512

host (str): Server hostname

513

port (int): Server port

514

515

Returns:

516

Deferred[FTPClient]: Connected client

517

"""

518

```

519

520

### Protocol Policies

521

522

Wrappers and policies for controlling protocol behavior.

523

524

```python { .api }

525

class policies.ProtocolWrapper:

526

"""

527

Base class for protocol wrappers.

528

"""

529

def __init__(self, protocol, factory):

530

"""

531

Args:

532

protocol: Wrapped protocol

533

factory: Wrapper factory

534

"""

535

536

class policies.WrappingFactory:

537

"""

538

Base factory for protocol wrappers.

539

"""

540

def __init__(self, wrappedFactory):

541

"""

542

Args:

543

wrappedFactory: Factory being wrapped

544

"""

545

546

def buildProtocol(self, addr):

547

"""

548

Build wrapped protocol.

549

550

Args:

551

addr: Connection address

552

553

Returns:

554

ProtocolWrapper: Wrapped protocol

555

"""

556

557

class policies.ThrottlingFactory:

558

"""

559

Factory that limits connection rate.

560

"""

561

def __init__(self, wrappedFactory, maxConnectionsPerIP=10):

562

"""

563

Args:

564

wrappedFactory: Factory being wrapped

565

maxConnectionsPerIP (int): Max connections per IP

566

"""

567

568

class policies.TimeoutFactory:

569

"""

570

Factory that enforces connection timeouts.

571

"""

572

def __init__(self, wrappedFactory, timeoutPeriod=30*60):

573

"""

574

Args:

575

wrappedFactory: Factory being wrapped

576

timeoutPeriod (int): Timeout in seconds

577

"""

578

579

class policies.TrafficLoggingFactory:

580

"""

581

Factory that logs all network traffic.

582

"""

583

def __init__(self, wrappedFactory, logfile):

584

"""

585

Args:

586

wrappedFactory: Factory being wrapped

587

logfile: File to log traffic to

588

"""

589

```

590

591

### Loopback Testing

592

593

Utilities for testing protocols without network connections.

594

595

```python { .api }

596

def loopback.loopback(server, client, pumpPolicy=None):

597

"""

598

Connect two protocols in loopback for testing.

599

600

Args:

601

server: Server protocol instance

602

client: Client protocol instance

603

pumpPolicy: Data pumping policy

604

605

Returns:

606

Deferred: Fires when loopback complete

607

"""

608

609

def loopback.loopbackTCP(server, client, port=0):

610

"""

611

Connect protocols via TCP loopback.

612

613

Args:

614

server: Server protocol instance

615

client: Client protocol instance

616

port (int): Port number (0 for random)

617

618

Returns:

619

Deferred: Fires when connection established

620

"""

621

622

def loopback.loopbackUNIX(server, client):

623

"""

624

Connect protocols via Unix socket loopback.

625

626

Args:

627

server: Server protocol instance

628

client: Client protocol instance

629

630

Returns:

631

Deferred: Fires when connection established

632

"""

633

```

634

635

**Loopback Testing Example**:

636

637

```python

638

from twisted.protocols import basic, loopback

639

from twisted.test import proto_helpers

640

from twisted.trial import unittest

641

642

class EchoProtocol(basic.LineReceiver):

643

def lineReceived(self, line):

644

self.sendLine(line)

645

646

class TestEcho(unittest.TestCase):

647

def test_echo_loopback(self):

648

server = EchoProtocol()

649

client = EchoProtocol()

650

651

# Set up data collection

652

client_data = []

653

def collect_data(line):

654

client_data.append(line)

655

client.lineReceived = collect_data

656

657

# Run loopback test

658

d = loopback.loopback(server, client)

659

660

# Send test data

661

client.sendLine(b"Hello")

662

client.sendLine(b"World")

663

664

# Verify echo

665

def check_result(_):

666

self.assertEqual(client_data, [b"Hello", b"World"])

667

668

d.addCallback(check_result)

669

return d

670

```

671

672

### Additional Protocol Implementations

673

674

Brief overview of other protocol implementations available in Twisted.

675

676

```python { .api }

677

# IRC Protocol (twisted.words.protocols.irc)

678

class irc.IRCClient:

679

"""IRC client protocol with event handlers."""

680

681

def joined(self, channel):

682

"""Called when joined a channel."""

683

684

def privmsg(self, user, channel, msg):

685

"""Called when receiving private message."""

686

687

# IDENT Protocol (twisted.protocols.ident)

688

class ident.IdentServer:

689

"""Ident server protocol (RFC 1413)."""

690

691

class ident.IdentClient:

692

"""Ident client protocol."""

693

694

# Memcached Protocol (twisted.protocols.memcache)

695

class memcache.MemCacheProtocol:

696

"""Memcached protocol client."""

697

698

def get(self, keys):

699

"""Get values by keys."""

700

701

def set(self, key, value, flags=0, expireTime=0):

702

"""Set key-value pair."""

703

704

# SOCKS Protocol (twisted.protocols.socks)

705

class socks.SOCKSv4:

706

"""SOCKS version 4 proxy protocol."""

707

708

class socks.SOCKSv4Factory:

709

"""SOCKS v4 factory."""

710

```