deftest_server(): # create a socket object s = socket.socket() print"Socket successfully created"
# reserve a port on your computer in our # case it is 12345 but it can be anything port = 12345
# Next bind to the port # we have not typed any ip in the ip field # instead we have inputted an empty string # this makes the server listen to requests # coming from other computers on the network s.bind(('', port)) print"socket binded to %s" % (port)
# put the socket into listening mode s.listen(5) print"socket is listening"
# a forever loop until we interrupt it or # an error occurs whileTrue: # Establish connection with client. c, addr = s.accept() print'Got connection from', addr
# send a thank you message to the client. c.send('Thank you for connecting') # Close the connection with the client c.close()
test_server()
1 2 3 4 5
Socket successfully created socket binded to 12345 socket is listening
Got connection from ('127.0.0.1', 57326)
对于 Server:
创建一个 socket, socket.socket()
bind 端口和地址, s.bind((‘’, port))
listen 端口监听 s.listen(5)
accept 接受连接
recv, send 接收和发送数据
close 关闭连接
Socket Client
1 2 3 4 5 6 7 8 9 10 11 12 13 14
import socket
deftest_client(): s = socket.socket() # Define the port on which you want to connect port = 12345 # connect to the server on local computer s.connect(('127.0.0.1', port)) # receive data from the server print s.recv(1024) # close the connection s.close()
test_client()
1
Thank you for connecting
对于 Client:
创建一个 socket
connect 与服务器建立连接
recv, send 接收和发送数据
close 关闭连接
中间的过程和细节
建立连接
对于一个客户端程序,建立 socket 需要两个步骤:
建立一个实际的 socket
连接到远端的服务器上
建立 socket 的时候需要告诉系统两件事情:
通信类型, 即用什么协议来传输数据,比如 IPv4, IPv6, AFP(Apple 文件共享)。大部分时候是 Internet 通信,所以通信类型是 AF_INET
classMyTCPHandler(SocketServer.BaseRequestHandler): """ The request handler class for our server. It is instantiated once per connection to the server, and must override the handle() method to implement communication to the client. """
defhandle(self): # self.request is the TCP socket connected to the client self.data = self.request.recv(1024).strip() print"{} wrote:".format(self.client_address[0]) 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
# Create the server, binding to localhost on port 9999 server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
# Activate the server; this will keep running until you # interrupt the program with Ctrl-C server.serve_forever()
"""Base class for request handler classes. This class is instantiated for each request to be handled. The constructor sets the instance variables request, client_address and server, and then calls the handle() method. To implement a specific service, all you need to do is to derive a class which defines a handle() method. The handle() method can find the request as self.request, the client address as self.client_address, and the server (in case it needs access to per-server information) as self.server. Since a separate instance is created for each request, the handle() method can define arbitrary other instance variariables. """
"""Define self.rfile and self.wfile for stream sockets."""
# Default buffer sizes for rfile, wfile. # We default rfile to buffered because otherwise it could be # really slow for large data (a getc() call per byte); we make # wfile unbuffered because (a) often after a write() we want to # read and we need to flush the line; (b) big writes to unbuffered # files are typically optimized by stdio even when big reads # aren't. rbufsize = -1 wbufsize = 0
# A timeout to apply to the request socket, if not None. timeout = None
# Disable nagle algorithm for this socket, if True. # Use only when wbufsize != 0, to avoid small packets. disable_nagle_algorithm = False
deffinish(self): ifnot self.wfile.closed: try: self.wfile.flush() except socket.error: # A final socket error may have occurred here, such as # the local error ECONNABORTED. pass self.wfile.close() + self.rfile.close()
def_eintr_retry(func, *args): """restart a system call interrupted by EINTR""" whileTrue: try: return func(*args) except (OSError, select.error) as e: if e.args[0] != errno.EINTR: raise
defserve_forever(self, poll_interval=0.5): """Handle one request at a time until shutdown. Polls for shutdown every poll_interval seconds. Ignores self.timeout. If you need to do periodic tasks, do them in another thread. """ self.__is_shut_down.clear() try: whilenot self.__shutdown_request: # XXX: Consider using another file descriptor or # connecting to the socket to wake this up instead of # polling. Polling reduces our responsiveness to a # shutdown request and wastes cpu at all other times. r, w, e = _eintr_retry(select.select, [self], [], [], poll_interval) if self in r: self._handle_request_noblock() finally: self.__shutdown_request = False self.__is_shut_down.set()