Creating a TCP-socket, for the family, you must use a socket.AF_INET or socket.AF_INET6 and for the type you must use socket.SOCK_STREAM.Example for Python socketimport sockets=socket.socket(socket.AF_INET, socket.SOCK_STREAM)Main methods to create Python socket objectsbind() – specific for server sockets.listen() – specific for server sockets.accept() – specific for server sockets.connect() – client sockets.send() – both server and client sockets.recv() – both server and client sockets.For instance, echo server from documentationimport sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.bind((‘localhost’, 50000))s.listen(1)conn, addr = s.accept()while 1: data = conn.recv(1024) if not data: break conn.sendall(data)conn.close()To create a server socket, bind it to localhost and 50000 port, and start listening for incoming connections.
A client-side code looks simplyimport sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((‘localhost’, 50000))s.sendall(‘Hello, world’)data = s.recv(1024)s.close()print ‘Received’, repr(data)Here instead of bind() and listen() methods it calls only the connect() method and directly sends data to the server.
The possible solution is to delegate working with clients to separate process/threads, creating any process and swap contexts between them is not a cheap operation.
The main idea is to maintain the socket’s state to an OS and check the program when there is something to read from the socket or when it is ready for writing.There are a group of interfaces for various operating systems:poll, epoll (Linux).kqueue, kevent (BSD).select (cross-platform).To create a server using Python selectimport select, socket, sys, Queueserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.setblocking(0)server.bind((‘localhost’, 50000))server.listen(5)inputs = [server]outputs = []message_queues = {}while inputs: readable, writable, exceptional = select.select( inputs, outputs, inputs) for s in readable: if s is server: connection, client_address = s.accept() connection.setblocking(0) inputs.append(connection) message_queues[connection] = Queue.Queue() else: data = s.recv(1024) if data: message_queues[s].put(data) if s not in outputs: outputs.append(s) else: if s in outputs: outputs.remove(s) inputs.remove(s) s.close() del message_queues[s] for s in writable: try: next_msg = message_queues[s].get_nowait() except Queue.Empty: outputs.remove(s) else:s.send(next_msg) for s in exceptional: inputs.remove(s) if s in outputs: outputs.remove(s) s.close() del message_queues[s]There is much more code than in the blocking Echo server.
That is principal ’cause we need to maintain a set of queues for different lists of sockets, i.e.
writing, reading, and a separate list for erroneous sockets.Creating a server socket looks the same except for within a line: server.setblocking(0).