python网络编程

Python网络编程

先导知识

    在了解并用python网络编程之前,首先需要了解的是计算机网络的基本架构和相关的知识,主要的重点有计算机网络的架构等。现在我发现有个网站整理的不错,因此先将该网站的链接放在这

https://book.apeland.cn/details/410/

   如果有觉得需要补充的知识或者看到有用的相关的知识,我会补充在这下面

 

代码实践

现在假设了解了上面的先导知识后,用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")

 

 

 

posted @ 2020-05-08 21:23  蟹老板bb  阅读(239)  评论(0)    收藏  举报