subprocess module
1. The terminal can help you through the operating system command code execution
And returns the result of the terminal 2. Run
Note: stdout stderr must be in front
import subprocess
cmd=input('cmd>>>:')
obj=subprocess.Popen(
cmd,shell=True,
stdout=subprocess.PIPE,#返回正确结果参数
stderr=subprocess.PIPE#返回错误结果参数
)
result=obj.stdout.read()+obj.stderr.read()
print(result.decode('gbk'))
Stick package problem
Data sent from the server for the first time, received a single client can not be accurately completed. The next data transmitted on the primary data stick together.
1. The need to accept the other party can not predict the size of the data length
2. multiple successive data transmit small amounts of data, and the time interval is shorter disposable package sent
TCP protocol features:
tcp is a streaming protocol will send several successive small amount of data, and the time interval is short data package sent disposable
Stick package to solve the problem
struct module
It may be a very long length data, compressed to a fixed mark length (data header).
We must first define the header, sending a header, and then send real data
That is the description of want to send a file, and want to send the file
'''
-struct模块:
是一个可以将很长的数据的长度,压缩成固定的长度的一个标记(数据报头)
'''
import struct
#打包压缩
# i模式,会将数据长度压缩成4个bytes
str1='nihaoyanihaoyanihaoya'
# 报头
headers=struct.pack('i', len(str1))
data_len=struct.unpack('i',headers)
print(data_len)#(21,)
print(data_len[0])#21
Stick package to solve the problem
#服务端
import socket
import subprocess
import struct
server=socket.socket()
server.bind(('127.0.0.1',9527))
server.listen(5)
while True:
conn,addr=server.accept()
while True:
try:
cmd=conn.recv(1024).decode('utf-8')
if cmd=='q':
break
if len(cmd)==0:
continue
print(cmd)
# 执行cmd命令
obj=subprocess.Popen(cmd,shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,)
#接受终端返回的数据
result=obj.stdout.read()+obj.stderr.read()
#打包压缩,获取报头
headers=struct.pack('i',len(result))
#发送报头
conn.send(headers)
#发送真实数据
conn.send(result)
except Exception as e:
print(e)
break
conn.close()
#客户端
import socket
import struct
client=socket.socket()
client.connect(('127.0.0.1',9527))
while True:
cmd=input('>>>:')
client.send(cmd.encode('utf-8'))
if cmd=='q':
break
#获取数据报头
headers=client.recv(4)
#解包,获取真实数据长度
data_len=struct.unpack('i',headers)
#获取真实数据
data=client.recv(data_len[0])
print(data.decode('gbk'))
client.close()
Upload dictionary
#服务端
import socket
import json
import struct
server=socket.socket()
server.bind(('127.0.0.1',8888))
server.listen(5)
while True:
conn,addr=server.accept()
while True:
try:
headers=conn.recv(4)
data_len=struct.unpack('i',headers)[0]
bytes_data=conn.recv(data_len)
#先解码再反序列化
back_dic=json.loads(bytes_data.decode('utf-8'))
print(back_dic)
except Exception as e:
print(e)
break
conn.close()
#客户端
import socket
import struct
import json
import time
cilent=socket.socket()
cilent.connect(('127.0.0.1',8888))
while True:
send_dic={
'file_name':'nick真实写真集.avi',
'file_size':1000000
}
#json序列化,并转换成bytes类型数据
json_data=json.dumps(send_dic)
bytes_data=json_data.encode('utf-8')
# 先做报头
headers=struct.pack('i',len(bytes_data))
cilent.send(headers)
cilent.send(bytes_data)
time.sleep(3)
Upload large files
#服务端
import socket
import json
import struct
server=socket.socket()
server.bind(('127.0.0.1',8888))
server.listen(3)
while True:
conn,addr=server.accept()
while True:
try:
#获取字典报头
headers=conn.recv(4)
#解包获取字典数据长度
data_len=struct.unpack('i',headers)[0]
#获取字典真实数据
bytes_dic=conn.recv(data_len)
#樊=反序列得到字典
back_dic=json.loads(bytes_dic.decode('utf-8'))
print(back_dic)
#得到字典的文件名以及视频文件按的大小
file_name=back_dic['file_name']
file_size=back_dic['file_size']
init_data=0
#打开文件 准备写入
with open(file_name,'wb') as f:
while init_data<file_size:
data=conn.recv(1024)
f.write(data)
init_data+=len(data)
num=init_data/file_size
print(f'已接受{num:.2%}')
print(f'{file_name}接收完毕')
except Exception as e:
print(e)
break
conn.close()
#客户端
import socket
import struct
import json
client=socket.socket()
client.connect(('127.0.0.1',8888))
#打开一个视频文件,获取视频数据大小
with open(r'C:\Users\zqf\Desktop\新建文件夹\八重樱_桃源恋歌_1080p.mp4','rb') as f:
movie_bytes=f.read()
# 为视频文件组织一个字典,字典内有视频文件按的名称和大小
send_dic={
'file_name':'八重樱-桃源恋歌',
'file_size':len(movie_bytes)
}
# 先打包字典 发送报头,再发送字典真实数据
json_data=json.dumps(send_dic)
bytes_data=json_data.encode('utf-8')
headers=struct.pack('i',len(bytes_data))
# 发送报头
client.send(headers)
#发送字典真实数据
client.send(bytes_data)
# 发送视频真实数据
init_data=0
with open(r'C:\Users\zqf\Desktop\新建文件夹\八重樱_桃源恋歌_1080p.mp4','rb') as f:
while init_data<len(movie_bytes):
send_data=f.read(1024)
client.send(send_data)
num=init_data/len(movie_bytes)
print(f'数据传输{num:.2%}')
init_data+=len(send_data)
UDP
It is a transport protocol
1. The need to establish a two-way pipeline
2. The package will not stick
3. The client sends data to the server without waiting for the server to accept successful return
4. loss of data content, data is insecure
-TCP: like to call
-UDP: like texting
#服务端
import socket
#.SOCK_DGRAM代表了UDP
server=socket.socket(type=socket.SOCK_DGRAM)
#绑定了ip+port
server.bind(('127.0.0.1',8888))
msg,addr=server.recvfrom(1024)
msg1,addr1=server.recvfrom(1024)
msg2,addr2=server.recvfrom(1024)
print(msg,msg1,msg2)
#客户端
import socket
client=socket.socket(type=socket.SOCK_DGRAM)
server_ip_port=(('127.0.0.1',8888))
client.sendto(b'hello',server_ip_port)
client.sendto(b'hello',server_ip_port)
client.sendto(b'hello',server_ip_port)
client.sendto(b'hello',server_ip_port)
client.sendto(b'hello',server_ip_port)
QQ chat room
#服务端
import socket
server=socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8888))
while True:
msg,addr=server.recvfrom(1024)
print(addr)
print(msg.decode('utf-8'))
send_msg=input("客户端向服务端发消息").encode('utf-8')
server.sendto(send_msg,addr)
#客户端
import socket
client=socket.socket(type=socket.SOCK_DGRAM)
server_ip_port=('127.0.0.1',8888)
while True:
send_msg=input('客户端向服务端发消息').encode('utf-8')
client.sendto(send_msg,server_ip_port)
msg=client.recv(1024)
print(msg.decode('utf-8'))
SocketServer
python built-in module, the socket can be simplified socket server code
- simplify TCP / UDP Service Code
- must create a class
#服务端
import socketserver
#必须定义类
#TCP:必须继承BaseRequestHandler类
class MyTcpServer(socketserver.BaseRequestHandler):
def handle(self):
print(self.client_address)
while True:
try:
#request.recv==conn.recv
data=self.request.recv(1024).decode('utf-8')
send_msg=data.upper()
self.request.send(send_msg.encode('utf-8'))
except Exception as e:
print(e)
break
if __name__ == '__main__':
#socketserver.TCPServer只能一个服务
# server=socketserver.TCPServer(
# ('127.0.0.1',8888),MyTcpServer
# )
#
#socketserver.ThreadingTCPServer 多个服务
server=socketserver.ThreadingTCPServer(
('127.0.0.1', 8888), MyTcpServer
)
server.serve_forever()
#客户端
import socket
client=socket.socket()
client.connect(
('127.0.0.1',8888)
)
while True:
send_msg=input('客户端:')
client.send(send_msg.encode('utf-8'))
back_msg=client.recv(1024)
print(back_msg.decode('utf-8'))