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 = ‘localhost‘
11 data_payload = 2048
12 backlog = 5
13
14
15 def echo_server(port):
16
17     # 创建一个TCP socket
18     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     # 这里设定为5
33     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)。第一个元素connection
40         # 是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。
41         client, address = sock.accept()
42
43         # 指定data最大长度为2048字节
44         data = 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部分指定,多用于实现非布尔的命令行flag
60         # (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.port
71     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 a
78     pair (host, port); the host must refer to the local host. For raw packet
79     sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])
80     """
81     pass
82 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 be
87     at least 0 (if it is lower, it is set to 0); it specifies the number of
88     unaccepted connections that the system will allow before refusing new
89     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 = ‘localhost‘
10
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 = 0
31         amount_expected = len(message)
32         while amount_received < amount_expected:
33             data = 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.port
50     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: b‘Test message, This will be echoed‘
 8 sent b‘Test message, This will be echoed‘ bytes back to (‘127.0.0.1‘, 62389)
 9 Waiting to receive message from client
10
11 3.客户端
12 Abel$ python3 1_13b_echo_client.py --port=9900
13 Connecting to localhost port 9900
14 Sending Test message, This will be echoed
15 Received: b‘Test message, This will be echoed‘
16 Closing connection to the server
时间: 2024-12-25 04:18:25

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

linux 网络编程之最简单的tcp通信客户端

编写一个最为简单的tcp通信客户端.代码如下: #include <iostream> #include <cstring> using namespace std; #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netinet/in.h> #include <errno.h> int main() { /*创

python高级编程 编写一个包1

#目的是:编写,发行python包可重复过程"""1:是缩短开始真正工作之前所需要的设置时间,也就是提供模板2:提供编写包的标准化方法3:简化测试驱动开发方法的使用4:为发行过程提供帮助5:用于所有包公用模式,描述所有python包之间相同之处和distutils和setuptools如何扮演核心角色6:产生式编程:(在维基百科里面搜索)如何通过基于模板方法对此提供帮助7:包模板创建,设置各种工作所需要的一切8:构建一个开发周期"""#用于所有包

Python——网络爬虫,一个简单的通用代码框架

一.代码"""通用代码框架:可使网页爬取变得更稳定更有效 下面是一个爬取百度网页的例子,正常情况下是返回"""import requests def get_HTML_Text(): try: r = requests.get(url, timeout=30) r.raise_for_status() # 若状态不是200,引发HTTPError异常 r.encoding = r.apparent_encoding return r.text e

Python网络编程 (三)使用select.select()实现聊天服务器

第一步, 实现通用的send()和receive()函数: send函数定义通过cPicle.dumps()将需要发送的数据序列化,然后通过socket.htonl()方法将序列化后的数据长度转化为网络字节序格式,以便于底层传输,再将网络字节序格式的长度打包为'L'类型的C struct, 最后发送打包后的长度以及序列化后的数据 receive函数即是send反向过程,先接收到打包后的长度,将其解包,然后再主机序列化,所有数据接收完成以后,返回解除序列化后的原始数据. 1 def send(ch

2017.07.09 Python网络编程之重用套接字地址

1.重用套接字地址: # -*- coding: UTF-8 -*-# 如果在某个端口上运行一个Python套接字服务器,连接一次后便终止了运行,就不能在使用这个端口了# !usr/bin/env python# Python Network Programming Cookbook --Chapter -1# This program is optimized for Python 2.7# It may run on any other version with/without modifi

python 网络编程要点

From http://www.zhihu.com/question/19854853 Python网络编程是一个很大的范畴,个人感觉需要掌握的点有:1. 如何使用Python来创建socket, 如何将socket与指定的IP地址和端口进行绑定,使用socket来发送数据,接受数据,2. 如何使用Python中处理线程,从而编写可以同时处理多个请求的web服务器3. 如何使用Python来控制HTTP层的逻辑,包括如何创建http GET,POST,PUT,DELETE请求,如何处理接受到的H

python网络编程初级

网络编程的专利权应该属于Unix,各个平台(如windows.Linux等).各门语言(C.C++.Python.Java等)所实现的符合自身特性的语法都大同小异.在我看来,懂得了Unix的socket网络编程,其他的形式的网络编程方法也就知道了.这句话说得还不太严谨.准确的应该说成懂得了socket编程的原理,网络编程也就知道了,不同之处就在于每个平台,每个语言都有自己专享的语法,我们直接灵活套用就行了. 下面是用python实现的最基本的网络编程的例子,即依托于客户端-服务器的架构,实现客户

python网络编程(一)

python网络编程(一). 功能:客户端向服务器发送一张图片. 服务器代码: 1 #!/user/bin/env python 2 # -*- coding:utf-8 -*- 3 import socket 4 sk = socket.socket() 5 sk.bind(('127.0.0.1', 8080, )) 6 sk.listen(5) 7 while True: 8 conn, address = sk.accept() 9 conn.sendall(bytes('欢迎登陆FTP

使用socket编程实现一个简单的文件服务器

使用socket编程实现一个简单的文件服务器.客户端程序实现put功能(将一个文件从本地传到文件服务器)和get功能(从文件服务器取一远程文件存为本地文件).客户端和文件服务器不在同一台机器上. put [-h hostname] [-p portname] local_filenameremote_filename get [-h hostname] [-p portname] remote_filenamelocal_filename 程序如下: 客户端Client.java package