作者:书友67696238 | 来源:互联网 | 2023-02-05 19:30
Python提供了两个级别访问的网络服务:低级别的网络服务支持基本的Socket,它提供了标准的BSDSocketsAPI,可以访问底层操作系统Socket接口的全部方法。高级别的
Python 提供了两个级别访问的网络服务:
- 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统 Socket 接口的全部方法。
- 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。
什么是 Socket?
Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
简单实例
服务端
我们使用 socket 模块的 socket 函数来创建一个 socket 对象。socket 对象可以通过调用其他函数来设置一个 socket 服务。
现在我们可以通过调用 bind(hostname, port) 函数来指定服务的 port(8080)。
接着,我们调用 socket 对象的 accept 方法。该方法等待客户端的连接,并返回 connection 对象,表示已连接到客户端。
1 #服务端代码
2 import socket
3 import subprocess
4 import struct
5 import json
6
7 phOne= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
8 phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 重复使用端口
9 phone.bind(('127.0.0.1', 8080))
10 phone.listen(5)
11 print('start...')
12 while True:
13 coon, client_add = phone.accept()
14 print(client_add)
15 while True:
16 try:
17 cmd = coon.recv(1024)
18 if not cmd:
19 break
20 obj = subprocess.Popen(
21 cmd.decode('utf-8'),
22 shell=True,
23 stdout=subprocess.PIPE,
24 stderr=subprocess.PIPE)
25 stdout = obj.stdout.read()
26 stderr = obj.stderr.read()
27 # 1.制作固定长度报头
28 header_dic = {
29 'filename': 'a.txt',
30 'md5': 'soigiojalks',
31 'total_size': len(stdout) + len(stderr)
32 }
33 header_json = json.dumps(header_dic)
34 header_bytes = header_json.encode('utf-8')
35 # 发送报头长度
36 coon.send(struct.pack('i', len(header_bytes)))
37 # 2.把报头发送给客户端
38 coon.send(header_bytes)
39 # 3.发送真实数据
40 coon.send(stdout)
41 coon.send(stderr)
42 except ConnectionResetError:
43 break
44 coon.close()
45 phone.close()
客户端
接下来我们写一个简单的客户端实例连接到以上创建的服务。端口号为 8080。
socket.connect(hosname, port ) 方法打开一个 TCP 连接到主机为 hostname 端口为 port 的服务商。连接后我们就可以从服务端获取数据,记住,操作完成后需要关闭连接。
完整代码如下:
1 # 客户端
2 import json
3 import socket
4 import struct
5
6 phOne= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
7 phone.connect(('127.0.0.1', 8080))
8 while True:
9 cmd = input('>>').strip()
10 if not cmd:
11 continue
12 phone.send(cmd.encode('utf-8'))
13 # 1.接收报头
14 header = phone.recv(4)
15 # 2.从报头中解析真实数据描述信息(报头长度)
16 header_size = struct.unpack('i', header)[0]
17 header_bytes = phone.recv(header_size)
18 header_json = header_bytes.decode('utf-8')
19 header_dic = json.loads(header_json)
20 print(header_dic)
21 total_size = header_dic['total_size']
22 recv_size = 0
23 recv_data = b''
24 while recv_size < total_size:
25 res = phone.recv(1024)
26 recv_data += res
27 recv_size += len(res)
28 print(recv_data.decode('utf-8'))
29 phone.close()
此代码已解决粘包问题!!!
网络编程常见面试题:
1.python中,网络编程有哪些常用模块?
2.socket对象内建方法有哪些?
3.HTTP是什么?它与HTTPS有什么区别?
4.说说HTTP请求报文与响应报文格式。
5.TCP为什么会粘包?
原文链接:https://www.cnblogs.com/FiveStars/p/15158516.html