循环链接
###服务端
import socket
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
###要实现循环链接,也就是一个链接段了之后,我们又可以继续链接其他的
##服务端要提供持续不断的服务
while True:
conn, addr = server.accept()
while True:
try:
data = conn.recv(1024) # b''
if len(data) == 0:break # 针对mac linux系统而言
print(data)
conn.send(data.upper())
except ConnectionResetError:
break
conn.close()
server.close()
###这个代码变成黄色,表示代码永远执行不到这里,
###上面是一个死循环,这个pycharm 自动检测到后的提示
##客户端
import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))
while True:
msg = input('please input your msg>>>:').encode('utf-8')
if len(msg) == 0:continue
client.send(msg)
data = client.recv(1024)
print(data)
模拟远程执行命令
##现在我们要写一个CS框架的程序,在之前的基础上,
##实现模拟远程输入一个命令,服务器执行,并将执行的结果发送给本地主机,并且打印出来
##但是因为执行的结果可能很长,所以会有粘包问题的产生 所以我们要重点解决粘包的问题
'''
解决思路:
1,客户端将命令发送到服务端, 服务端接收命令,这个接收命令就直接接收1024字节就可以 因为命令的长度一般不可能超过这个长度
2,服务端调用subprocess 模块,执行命令,然后得到执行的结果
3,因为执行得到的结果长度不确定,可能很大,也可能很小,所以我们需要将提前将结果的长度发过去
4,我们直接len() 得到需要传过去的数据的长度,然后利用 struct 模块,将这个长度数据转化成
##固定长度的数据 发送过去
5,客户端接收到这个数据长度之后,如果数据量很大,就循环接收拼接这个数据,然后将数据打印出来
'''
###服务端
import socket
import subprocess
import struct
import json
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
while True:
conn, addr = server.accept()
while True:
try:
cmd = conn.recv(1024).decode('utf-8')
if len(cmd) == 0:break
obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
print(len(stdout+stderr))
send_dic = {"name":'jason','password':'123','total_size':len(stdout+stderr)}
send_bytes = json.dumps(send_dic).encode('utf-8')
# 先制作字典的报头
header = struct.pack('i',len(send_bytes))
# 发送报头
conn.send(header)
# 再发字典
conn.send(send_bytes)
# 最后再发真实数据
conn.send(stdout+stderr)
except ConnectionResetError as e:
print(e)
break
conn.close()
server.close()
##客户端
import socket
import struct
import json
client = socket.socket()
client.connect(('127.0.0.1',8080))
while True:
cmd = input('please input your cmd>>>:').encode('utf-8')
if len(cmd) == 0:continue
client.send(cmd)
# 先接收报头
header = client.recv(4)
# 解析获取字典的长度
dic_len = struct.unpack('i',header)[0]
dic_bytes = client.recv(dic_len)
real_dic = json.loads(dic_bytes.decode('utf-8'))
print(real_dic)
# 循环接收真实数据
data = b''
recv_size = 0
while recv_size < real_dic['total_size']:
info = client.recv(1024)
data += info
recv_size += len(info)
print(data.decode('gbk'))
实现大文件上传
###服务端
import socket
import struct
import json
from socket import SOL_SOCKET,SO_REUSEADDR
server = socket.socket()
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
server.bind(('127.0.0.1',8080))
server.listen(5)
conn,addr = server.accept()
# 先收4个长度报头
header = conn.recv(4)
# 获取字典长度
dic_len = struct.unpack('i',header)[0]
# 接收字典
dic_bytes = conn.recv(dic_len)
real_dic = json.loads(dic_bytes.decode('utf-8'))
# 获取文件相关信息
file_name = real_dic.get('file_name')
total_size = real_dic.get("file_size")
with open(file_name,'wb') as f:
# 循环接收文件
recv_size = 0
while recv_size < total_size:
data = conn.recv(1024)
f.write(data)
recv_size += len(data)
print('文件上传成功')
##客户端
import socket
import struct
import json
import os
client = socket.socket()
client.connect(('127.0.0.1',8080))
file_path = r'D:python周末四期day111.时间模块.mp4'
file_size = os.path.getsize(file_path) # 获取文件大小
send_dic = {"file_name":'FBI warning','file_info':"注意身体",'file_size':file_size}
send_bytes = json.dumps(send_dic).encode('utf-8')
# 制作报头
head = struct.pack('i',len(send_bytes))
# 发送报头
client.send(head)
# 发字典
client.send(send_bytes)
# 发文件
with open(file_path,'rb') as f:
for line in f:
client.send(line)