Socket Server
Server Types
- BaseServer, defines APIs
- handle_request(), handle request once
- serve_forever(), calls handle_request() in an infinite loop
- TCPServer, use TCP/IP socket to communicate
- UDPServer, use UDP socket to communicate
- UnixStreamServer and UnixDatagramServer, use UDS to communicate
Handlers
- BaseRequestHandler
- setup(), called before the handle() method to perform any initialization actions required
- handle(), define what to do
- finish(), called after the handle() method to perform any clean-up actions required
- #server.py
- #!/usr/bin/python
-
- import SocketServer
-
- import SocketServer
-
- class MyTCPHandler(SocketServer.BaseRequestHandler):
- def handle(self):
- self.data = self.request.recv(1024).strip()
- print type(self.request), type(self.client_address), type(self.server)
- print 'Client: ', self.client_address
- print 'Server: ', self.server
- print self.data
- # just send back the same data, but upper-cased
- self.request.sendall(self.data.upper())
-
- if __name__ == "__main__":
- HOST, PORT = "localhost", 9999
- server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
-
- server.serve_forever()
-
- #client.py
- #!/usr/bin/python
-
- import socket
- import sys
-
- HOST, PORT = "localhost", 9999
-
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
- try:
- data = raw_input("Eneter your message:\n");
- sock.connect((HOST, PORT))
- sock.sendall(data + "\n")
-
- # Receive data from the server and shut down
- received = sock.recv(1024)
- finally:
- sock.close()
-
- print "Received: {}".format(received)
-
Flow Control
- #server.py
- #!/usr/bin/python
-
- import SocketServer
- import struct
-
- class MyTCPHandler(SocketServer.BaseRequestHandler):
-
- def __init__(self, request, client_address, server):
- self.n = 0;
- SocketServer.BaseRequestHandler.__init__(self, request, client_address, server)
-
- def handle(self):
- s = struct.Struct('f');
- while True:
- self.data = self.request.recv(s.size)
- self.unpacked_data = s.unpack(self.data)
- self.n += 1
- print 'received: ', self.n, self.unpacked_data[0]
-
- if __name__ == "__main__":
- HOST, PORT = "localhost", 9999
- server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
-
- server.serve_forever()
-
- #client.py
- #!/usr/bin/python
-
- import random
- import socket
- import sys
- import struct
-
- HOST, PORT = "localhost", 9999
-
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
- s = struct.Struct('f');
- num = 0;
-
- sock.connect((HOST, PORT))
-
- try:
- while True:
- n = random.random();
- packed = s.pack(n);#pack data into a string
- num += 1;
- print 'Sent: ', num, n
- sock.sendall(packed)
- finally:
- pass
- #sock.close()
-
Threading and Forking
- Threads, use the ThreadingMixIn
- Processes, use the ForkingMixIn
- #server.py
- import threading
- import SocketServer
- import socket
-
- class ThreadedEchoRequestHandler(SocketServer.BaseRequestHandler):
-
- def handle(self):
- # Echo the back to the client
- data = self.request.recv(1024)
- cur_thread = threading.currentThread()
- response = '%s: %s' % (cur_thread.getName(), data)
- print 'Received: ', response
-
- class ThreadedEchoServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
- pass
-
- if __name__ == '__main__':
- address = ('localhost', 50007) # let the kernel give us a port
- server = ThreadedEchoServer(address, ThreadedEchoRequestHandler)
- ip, port = server.server_address # find out what port we were given
- print ip, port
-
- t = threading.Thread(target=server.serve_forever)
- #t.setDaemon(True) # don't hang on exit
- t.start()
- print 'Server loop running in thread:', t.getName()
-
- #server.socket.close()
-
- import socket
- import threading
-
- address = ('localhost', 50007) # let the kernel give us a port
-
- # Connect to the server
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect(address)
-
- # Send the data
- message = 'Hello, world'
- print 'Sending : "%s"' % message
- len_sent = s.send(message)
-
- # Clean up
- s.close()
-