首页 > 代码库 > Python网络编程——编写一个简单的回显客户端/服务器应用

Python网络编程——编写一个简单的回显客户端/服务器应用

今天将python中socket模块的基本API学习完后,照着书上的实例编写一个套接字服务器和客户端。采用python3.5版本,在注释中会标明python2和python3的不同之处。

1.代码

(1)服务器端及对应代码解释

技术分享
 1 # ! /usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # 编写回显服务器 4  5 import socket 6 import sys 7 import argparse 8  9 # 定义常量10 host = localhost11 data_payload = 204812 backlog = 513 14 15 def echo_server(port):16 17     # 创建一个TCP socket18     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)19 20     # 设置TCP套接字关联选项——重用地址21     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)22 23     # 建立套接字端口24     server_address = (host, port)25     print("Starting up echo server on %s port %s" % server_address)26 27     # 将socket绑定到server_address地址28     sock.bind(server_address)29 30     # 监听客户端31     # backlog指定最多允许多少个客户连接到服务器。它的值至少为1。收到连接请求后,这些请求需要排队,如果队列满,就拒绝请求。32     # 这里设定为533     sock.listen(backlog)34     # 在调用 Listen 之前,必须首先调用 Bind 方法,否则 Listen 将引发 SocketException。35     while True:36         print("Waiting to receive message from client")37 38         # 调用accept方法时,socket会时入“waiting”状态。客户请求连接时,方法建立连接并返回服务器。39         # accept方法返回一个含有两个元素的 元组(connection,address)。第一个元素connection40         # 是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。41         client, address = sock.accept()42 43         # 指定data最大长度为2048字节44         data =http://www.mamicode.com/ client.recv(data_payload)45         if data:46             print("Data: %s" % data)47             client.send(data)48             print("sent %s bytes back to %s" % (data, address))49         # 关闭连接50         client.close()51 52 if __name__ == __main__:53     # 创建一个解析对象,其中描述为"Socket Error Examples"54     parser = argparse.ArgumentParser(description=Socket Server Example)55     # 采用add_argument方法56     # name or flags —— 必须的参数,该参数接收选项参数或者是位置参数57     # action:58         # (1)store —— 默认action模式,储存值到指定变量59         # (2)store_const —— 储存值在参数的const部分指定,多用于实现非布尔的命令行flag60         # (3)store_true/store_false —— 布尔开关。可以2个参数对应一个变量61         # (4)append —— 储存值到列表,储存值在参数的const部分指定62         # (5)append_const —— 储存值到列表,储存值在参数的const部分指定63         # (6)version —— 输出版本信息然后退出64     # type —— 把从命名行输入的结果转成设置的类型,通常用来检查值的范围,以及合法性。默认string  65     # required —— 指定某个选项在命名中出现, 默认False, 若为 True, 表示必须输入该参数66     # dest —— 把位置或者选项关联到一个特定的名字67     parser.add_argument(--port, action="store", dest="port", type=int, required=True)68     # 调用parse_args()方法进行解析69     given_args = parser.parse_args()70     port = given_args.port71     echo_server(port)72 73 def bind(self, address):  # real signature unknown; restored from __doc__74     """75     bind(address)76 77     Bind the socket to a local address.  For IP sockets, the address is a78     pair (host, port); the host must refer to the local host. For raw packet79     sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])80     """81     pass82 def listen(self, backlog=None):  # real signature unknown; restored from __doc__83     """84     listen([backlog])85 86     Enable a server to accept connections.  If backlog is specified, it must be87     at least 0 (if it is lower, it is set to 0); it specifies the number of88     unaccepted connections that the system will allow before refusing new89     connections. If not specified, a default reasonable value is chosen.90     """91     pass
服务器端代码

(2)客户端及对应代码解释

技术分享
 1 # ! /usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # 编写回显客户端 4  5 import socket 6 import sys 7 import argparse 8  9 host = localhost10 11 12 def echo_client(port):13     # 创建TCP socket连接14     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)15     # 获取服务器端host和端口号16     server_address = (host, port)17     print("Connecting to %s port %s" % server_address)18     sock.connect(server_address)19     20     try:21         # 将message内容发送到服务器端22         message = "Test message, This will be echoed"23         print("Sending %s" % message)24         # python2和python3此处不同25         # python2—— sock.sendall(message)26         # sendall()发送完整的TCP数据,成功返回None,失败抛出异常27         sock.sendall(message.encode())28         29         # 服务器端将发送的数据回传给客户端并打印30         amount_received = 031         amount_expected = len(message)32         while amount_received < amount_expected:33             data = http://www.mamicode.com/sock.recv(1024)34             amount_received += len(data)35             print("Received: %s" % data)36     # 处理相对应错误37     except socket.error as e:38         print("socket error: %s" % str(e))39     except Exception as e:40         print("Other exception: %s" % str(e))41     finally:42         print("Closing connection to the server")43         sock.close()44 45 if __name__ == __main__:46     parser = argparse.ArgumentParser(description=Socket Server Example)47     parser.add_argument(--port, action="store", dest="port", type=int, required=True)48     given_args = parser.parse_args() 49     port = given_args.port50     echo_client(port)
客户端代码

 (3)运行结果

 1 1. 服务器端 2 Abel$ python3 1_13a_echo_server.py --port=9900 3 Starting up echo server on localhost port 9900 4 Waiting to receive message from client 5  6 2.客户端发送数据时,服务器端 7 Data: bTest message, This will be echoed 8 sent bTest message, This will be echoed bytes back to (127.0.0.1, 62389) 9 Waiting to receive message from client10 11 3.客户端12 Abel$ python3 1_13b_echo_client.py --port=990013 Connecting to localhost port 990014 Sending Test message, This will be echoed15 Received: bTest message, This will be echoed16 Closing connection to the server

 

Python网络编程——编写一个简单的回显客户端/服务器应用