python网络编程
Python网络编程
先导知识
在了解并用python网络编程之前,首先需要了解的是计算机网络的基本架构和相关的知识,主要的重点有计算机网络的架构等。现在我发现有个网站整理的不错,因此先将该网站的链接放在这
如果有觉得需要补充的知识或者看到有用的相关的知识,我会补充在这下面
代码实践
现在假设了解了上面的先导知识后,用python代码来实现一些简单的网络编程demo
demo1:实现客户端从服务器下载文件
这段代码参考自:
https://www.cnblogs.com/xiaokang01/p/9069048.html
客户端代码:
1 import socket 2 import struct 3 import json 4 import time 5 from process_bar import process_bar 6 7 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 client.connect(('127.0.0.1', 50007)) 9 buffsize = 1024 10 11 print('等待连接服务端...') 12 while True: 13 # 接收报头的长度 14 head_struct = client.recv(4) 15 if head_struct: 16 print("-->已连接服务端,等待接收数据...") 17 # 解析出报头的字符串大小 18 head_len = struct.unpack('i', head_struct)[0] 19 # 接收长度为head_len的报头内容的信息(包含文件大小,文件名的内容) 20 data = client.recv(head_len) 21 22 head_dir = json.loads(data.decode("utf-8")) 23 filesize_b = head_dir['filesize_bytes'] 24 filename = head_dir['filename'] 25 26 # 接收文件真实内容 27 recv_len = 0 28 recv_msg = b'' 29 old = time.time() 30 f = open(filename, 'wb') 31 while recv_len < filesize_b: 32 percent = recv_len / filesize_b 33 34 process_bar(percent) 35 if filesize_b - recv_len > buffsize: 36 recv_msg = client.recv(buffsize) 37 f.write(recv_msg) 38 recv_len += len(recv_msg) 39 else: 40 recv_msg = client.recv(filesize_b-recv_len) 41 recv_len += len(recv_msg) 42 f.write(recv_msg) 43 44 print(recv_len, filesize_b) 45 now = time.time() 46 stamp = int(now-old) 47 print('总共用时: {}'.format(stamp)) 48 f.close()
服务器端代码:
1 import socket 2 import struct 3 import json 4 import os 5 6 HOST = "127.0.0.1" 7 port = 50007 8 buffsize = 1024 9 10 sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 11 sock_server.bind((HOST, port)) 12 sock_server.listen() # 开始监听,1代表在允许有一个连接排队,更多的新连接连进来时就会被拒绝 13 print("--->还没有人连接......") 14 while True: 15 """ 连接循环 """ 16 conn, addr = sock_server.accept() 17 18 print("--->连接人的信息:", addr) 19 while True: 20 if not conn: 21 print('客户连接中断...') 22 break 23 """ 通信循环 """ 24 filemsg = input('--->请输入要传送的文件名加后缀>>>').strip() 25 26 filesize_bytes = os.path.getsize(filemsg) # 得到文件的大小,字节 27 filename = 'new_' + filemsg 28 dirc = { 29 'filename': filename, 30 'filesize_bytes': filesize_bytes, 31 } 32 head_info = json.dumps(dirc) # 将字典转换成字符串 33 head_info_len = struct.pack('i', len(head_info)) 34 # 将字符串的长度打包 35 # 先将报头转换成字符串(json.dumps), 再将字符串的长度打包 36 # 发送报头长度,发送报头内容,最后放真是内容 37 # 报头内容包括文件名,文件信息,报头 38 # 接收时:先接收4个字节的报头长度, 39 # 将报头长度解压,得到头部信息的大小,在接收头部信息, 反序列化(json.loads) 40 # 最后接收真实文件 41 conn.send(head_info_len) # 发送head_info的长度 42 conn.send(head_info.encode('utf-8')) 43 44 # 发送真实信息 45 with open(filemsg, 'rb') as f: 46 data = f.read() 47 conn.sendall(data) 48 49 print('发送成功!!!')
模拟加载模块代码:
1 def process_bar(percent, width=50): 2 use_num = int(percent*width) 3 space_num = int(width-use_num) 4 percent = percent * 100 5 print("{}{}--{}%".format(use_num*'#', space_num*' ', percent, flush=True, end='\r'))
运行结果:
服务器端:

客户端:


demo2: socket通信模拟http请求
该段代码首先需要了解基本的http协议,知道客户端的浏览器和服务器进行通信时的请求和响应的报文格式,推荐书籍:图解http, 我这有个pdf书籍的链接:https://pan.baidu.com/s/12jN8W
1 import socket 2 from urllib.parse import urlparse 3 4 5 def get_url(url): 6 # 通过socket请求html 7 url = urlparse(url) 8 host = url.netloc 9 path = url.path 10 if path == "": 11 path = "/" 12 13 # 建立socket链接 14 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 15 client.connect((host, 80)) 16 17 # 发送的数据要符合http协议 18 client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format(path, host).encode("utf-8")) 19 20 data = b"" 21 while True: 22 d = client.recv(1024) 23 if d: 24 data += d 25 else: 26 break 27 data = data.decode("utf-8") 28 # 将响应报头和主体分开 29 html_data = data.split("\r\n\r\n")[0] 30 print(html_data) 31 client.close() 32 33 34 if __name__ == "__main__": 35 get_url("https://www.baidu.com")

浙公网安备 33010602011771号