Sumátor
Toto je server implementujúci jednoduchý protokol. Server vie sčítať čísla.
Protokol je takýto:
Klient |
Význam príkazu |
Server |
Cislo n |
pripočíta číslo n k sume |
OK |
Suma |
vypíše sumu a znuluje ju |
Suma je suma |
Dovi |
napíše Dovi a uzavrie spojenie |
Dovi |
niečo_iné |
chyba |
Error niečo_iné |
Vyskúšať server možno cez
telnet localhost 2222
1 #!/usr/bin/env python
2 import socket
3 import sys
4 import os
5 import signal
6 import re
7
8
9 # Skuste:
10 # telnet 127.0.0.1 2222
11 # ukoncite CTRL-] a potom quit
12 # alebo prikazom Dovi
13
14 # Protokol:
15 #
16 # Cislo n -> OK
17 # Suma -> Suma je ...
18 # Dovi -> Dovi
19
20 # Vytvorime TCP socket
21 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
22 # Naviazeme ho na port 2222 pre vsetky lokalne adresy
23 s.bind(('',2222))
24 # Najviac 5 spojeni bude cakat vo fronte
25 s.listen(5)
26
27 # Toto je kvoli tomu, aby nam nezostavali zombie
28 # procesy a neprerusoval nas signal SIGCHLD
29 signal.signal(signal.SIGCHLD,signal.SIG_IGN)
30
31 try:
32 while True:
33 connected_socket,address=s.accept()
34 print 'Connected by',address
35 # Po pripojeni klienta sa forkneme.
36 # Child proces obsluzi klienta a zavola sys.exit()
37 # Parent proces ocakava
38 # dalsieho klienta.
39 pid_chld=os.fork()
40 if pid_chld<0:
41 print "fork vratil chybu"
42 sys.exit(1)
43 if pid_chld==0:
44 # Toto robi child proces.
45 # Vytvorime si file object z pripojeneho
46 # socketu
47 f=connected_socket.makefile()
48 sum=0
49 for line in f:
50 # Precitame, co klient chce
51 # a dame mu odpoved
52 m=re.match(r'Cislo (\d*)\s*',line)
53 if m:
54 sum=sum+int(m.groups()[0])
55 f.write('OK\n')
56 elif re.match(r'Suma\s*',line):
57 f.write('Suma je %d\n' % sum)
58 sum=0
59 elif re.match(r'Dovi\s*',line):
60 f.write('Dovi\n')
61 f.flush()
62 break
63 else:
64 f.write('Error: %s' % line)
65 # Toto zabezpeci, ze sa odpoved
66 # posle ihned klientovi - inak to ide do buffra
67 f.flush()
68 # f je duplikovany connected_socket, preto
69 # ho musime zavriet osobitne.
70 f.close()
71 # Takymto sposobom sa spravne zatvara
72 # socket, v prikladoch v dokumentacii to
73 # je zle.
74 connected_socket.shutdown(socket.SHUT_RDWR)
75 connected_socket.close()
76 print address,'disconnected'
77 sys.exit(0)
78 except KeyboardInterrupt:
79 pass
80 s.close()