尝试过Python中socket模块的基本API后,现在我们来编写一个套接字服务器和客户端。这里,你将有机会利用在前述攻略中掌握的基本知识。 1.14.1 实战演练 在这个例子中,不管服务器从客户端收到什么输入,都会将其回显出来。我们要使用Python中的argparse模块,在命令行中指定TCP端口。服务器脚本和客户端脚本都要用到这个参数。 我们先来编写服务器。首先创建一个TCP套接字对象。然后设定启用重用地址,这样想运行多少次服务器就能运行多少次。我们把套接字绑定在本地设备的指定端口上。在监听阶段,把backlog参数传入listen()方法中,让服务器在队列中监听多个客户端。最后,等待客户端连接,向服务器发送一些数据。收到数据后,服务器会把数据回显给客户端。 代码清单1-13a展示了如何编写回显应用的服务器,如下所示: #!/usr/bin/env python # Python Network Programming Cookbook -- Chapter – 1 # This program is optimized for Python 2.7. It may run on any # other Python version with/without modifications. import socket import sys import argparse host = 'localhost' data_payload = 2048 backlog = 5 def echo_server(port): """ A simple echo server """ # Create a TCP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Enable reuse address/port sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Bind the socket to the port server_address = (host, port) print "Starting up echo server on %s port %s" % server_address sock.bind(server_address) # Listen to clients, backlog argument specifies the max no. of queued connections sock.listen(backlog) while True: print "Waiting to receive message from client" client, address = sock.accept() data = client.recv(data_payload) if data: print "Data: %s" %data client.send(data) print "sent %s bytes back to %s" % (data, address) # end connection client.close() if __name__ == '__main__': parser = argparse.ArgumentParser(description='Socket Server Example') parser.add_argument('--port', action="store", dest="port", type=int, required=True) given_args = parser.parse_args() port = given_args.port echo_server(port) 在客户端代码中,我们要创建一个客户端套接字,然后使用命令行参数中指定的端口连接服务器。客户端把消息Test message. This will be echoed发送给服务器之后,立即就会在几个数据片段中收到返回的消息。这里用到了两个try-except块,捕获交互过程中发生的任何异常。 代码清单1-13b展示了如何编写回显程序的客户端,如下所示: #!/usr/bin/env python # Python Network Programming Cookbook -- Chapter – 1 # This program is optimized for Python 2.7. It may run on any # other Python version with/without modifications. import socket import sys import argparse host = 'localhost' def echo_client(port): """ A simple echo client """ # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect the socket to the server server_address = (host, port) print "Connecting to %s port %s" % server_address sock.connect(server_address) # Send data try: # Send data message = "Test message. This will be echoed" print "Sending %s" % message sock.sendall(message) # Look for the response amount_received = 0 amount_expected = len(message) while amount_received < amount_expected: data = sock.recv(16) amount_received += len(data) print "Received: %s" % data except socket.errno, e: print "Socket error: %s" %str(e) except Exception, e: print "Other exception: %s" %str(e) finally: print "Closing connection to the server" sock.close() if __name__ == '__main__': parser = argparse.ArgumentParser(description='Socket Server Example') parser.add_argument('--port', action="store", dest="port", type=int, required=True) given_args = parser.parse_args() port = given_args.port echo_client(port) 1.14.2 原理分析 为了查看客户端和服务器之间的交互,要在一个终端里启动如下服务器脚本: $ python 1_13a_echo_server.py --port=9900 Starting up echo server on localhost port 9900 Waiting to receive message from client 然后,在另一个终端里运行客户端,如下所示: $ python 1_13b_echo_client.py --port=9900 Connecting to localhost port 9900 Sending Test message. This will be echoed Received: Test message. Th Received: is will be echoe Received: d Closing connection to the server 连接到本地主机后,服务器还会输出以下消息: Data: Test message. This will be echoed sent Test message. This will be echoed bytes back to ('127.0.0.1', 42961) Waiting to receive message from client
Python网络编程攻略——1.14 编写一个简单的回显客户端/服务器应用
书名: Python网络编程攻略
作者: 萨卡尔
出版社: 人民邮电出版社
译者: 安道
出版年: 2014-12-1
页数: 170
定价: 45.00元
装帧: 平装
丛书: 图灵程序设计丛书
ISBN: 9787115372697