Browse Source

initial commit

master
zhanglei 3 months ago
parent
commit
27462c5eb5
  1. 33
      README.txt
  2. 877
      main.py.bak

33
README.txt

@ -1,24 +1,23 @@
windows 开启xftp(目前版本: frp_0.53.2_windows_amd64 ) 操作说明:
在./P2PfilePython文件夹下右击打开终端 本软件不需要安装为免安装绿色软件。
需在系统 windows环境上运行主程序SnailSend.exe,选下面密钥一个密钥才可以发送和接收文件。(注意:发送和接收密钥必须一致,必须为同一个)
发送文件可以开多个程序同时发送,但接收文件只能要开一个。(注意:接收文件开多个会将影响原先接收程序)
密钥可以重复使用,如遇到密钥已经被占用的情况请换一个密钥。
请关闭你的网络开启UDP防护,避免接收不到文件。
#发送命令 (windows) 误杀说明:
有些杀毒软件会将本软件视为病毒,可以关闭杀毒软件。
python.exe .\p2pfile.py --mode send --host 127.0.0.1 --port 7001 --path D:\navidrome-data.zip --psk 123456@@ 密钥:
1. ENbOUMvXJGWuA623@@@|MyvKorrmGv3Xn8FTARkiTy3mvRwTJGrE|2zxJDn9LzF4CFjHspBTmdRHuh6ew11C5|Q6XThKq457kLuwERbUPPMEnxjYUzVKGk
#接收命令 (windows) 2. ENbOUMvXJGWuA623@@@|2E8UaE0qQm8bVtAFqzUhXJWMbPjBh8Gq|0AqiomQgKGpzea89ZbhWeRVNJ7crXZt6|JjTTRBiq89o9Lm4Zg6bgjpeXc9NBU5tz
python.exe .\p2pfile.py --mode recv --host 47.97.6.201 --port 6000 --outdir ./ --psk 123456@@ 3. ENbOUMvXJGWuA623@@@|7tKyGbtCcwiWb8ZvDjLMDCUDgunsE9x7|5ToF67sH35W64Pf6sPz1BTCPfB5sNcuF|vZ9McB85fHfvumBjxUzRrb416TATE8EP
python3 ./p2pfile.py --mode recv --host 127.0.0.1 --port 6000 --outdir ./ --psk 123456 4. ENbOUMvXJGWuA623@@@|E6egfQoUog2rpGRhr2VhtrZE3V4WTBij|b3v6XxVPvcWuuau2uKPqHhTV4KZ74kZi|MW1Bm9NPy4fdqTcE3N9RxijP8U319V2s
5. ENbOUMvXJGWuA623@@@|aw1fohFnPcZEjRcRogENJzBbgPsNqjV3|Lcaa6hmVU7nXKoHmZDYp3EnaUbTfARnh|M0BUnkgzPxR0Ebdp9NQ4VUtm4EpTDvPR
参数说明: 作者:蜗牛
--mode", choices=["send", "recv"], required=True) 邮件:mvcers@gmail.com
--host", help="接收端IP (send模式必需)")
--port", type=int, required=True)
--path", help="要发送的文件/目录 (send模式必需)")
--outdir", help="接收保存目录 (recv模式必需)")
--rate", help="限速,例: 500K, 5M(每连接)")
--psk", required=True, help="预共享密钥,用于保证不被串口,可自定义")
--conn", type=int, default=4, help="并行连接数,默认 4")
--part-size", type=int, default=64, help="分片大小(MB),默认 64")

877
main.py.bak

@ -1,877 +0,0 @@
import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext, filedialog
import threading
import subprocess
import os
import sys
import time
import random
import subprocess
from subprocess import CREATE_NO_WINDOW, STARTUPINFO, STARTF_USESHOWWINDOW
class FileTransferApp:
def __init__(self, root):
self.root = root
self.root.title("蜗牛创造的高速文件传输")
self.root.geometry("900x700")
self.root.configure(bg='white') # 设置窗口背景为白色
# 设置样式
self.setup_styles()
# 创建主框架容器
self.main_frame = tk.Frame(self.root, bg='white')
self.main_frame.pack(fill='both', expand=True, padx=20, pady=20)
# 显示欢迎界面
self.show_welcome_screen()
def setup_styles(self):
"""设置界面样式"""
style = ttk.Style()
style.configure('TButton', font=('Microsoft YaHei', 10))
style.configure('Primary.TButton', background='#3498db', foreground='white')
style.configure('Success.TButton', background='#2ecc71', foreground='white')
style.configure('Danger.TButton', background='#e74c3c', foreground='white')
style.configure('Secondary.TButton', background='#95a5a6', foreground='white')
def clear_frame(self):
"""清除当前框架中的所有控件"""
for widget in self.main_frame.winfo_children():
widget.destroy()
def show_welcome_screen(self):
"""显示欢迎界面"""
self.clear_frame()
# 顶部logo区域
logo_frame = tk.Frame(self.main_frame, bg='white')
logo_frame.pack(pady=(30, 20))
# 欢迎标签
welcome_label = tk.Label(
logo_frame,
text="🐌 欢迎来到蜗牛创造的高速世界",
font=("Microsoft YaHei", 20, "bold"),
fg="#2c3e50",
bg='white'
)
welcome_label.pack()
# 副标题
subtitle_label = tk.Label(
logo_frame,
text="安全、高速的文件传输解决方案",
font=("Microsoft YaHei", 12),
fg="#7f8c8d",
bg='white'
)
subtitle_label.pack(pady=(5, 30))
# 功能卡片框架
card_frame = tk.Frame(self.main_frame, bg='white')
card_frame.pack(pady=20)
# 发送卡片
send_card = tk.Frame(card_frame, bg='#f8f9fa', relief='raised', bd=1, padx=20, pady=20)
send_card.pack(side='left', padx=15)
send_icon = tk.Label(send_card, text="📤", font=("Arial", 24), bg='#f8f9fa')
send_icon.pack()
send_title = tk.Label(send_card, text="发送文件", font=("Microsoft YaHei", 14, "bold"), fg="#2c3e50", bg='#f8f9fa')
send_title.pack(pady=(10, 5))
send_desc = tk.Label(send_card, text="快速安全地发送文件", font=("Microsoft YaHei", 9), fg="#7f8c8d", bg='#f8f9fa')
send_desc.pack(pady=(0, 15))
send_button = tk.Button(
send_card,
text="开始发送",
command=self.show_send_screen,
font=("Microsoft YaHei", 11, "bold"),
bg="#3498db",
fg="white",
width=12,
height=2,
relief='flat',
cursor='hand2'
)
send_button.pack()
# 接收卡片
receive_card = tk.Frame(card_frame, bg='#f8f9fa', relief='raised', bd=1, padx=20, pady=20)
receive_card.pack(side='left', padx=15)
receive_icon = tk.Label(receive_card, text="📥", font=("Arial", 24), bg='#f8f9fa')
receive_icon.pack()
receive_title = tk.Label(receive_card, text="接收文件", font=("Microsoft YaHei", 14, "bold"), fg="#2c3e50", bg='#f8f9fa')
receive_title.pack(pady=(10, 5))
receive_desc = tk.Label(receive_card, text="安全可靠地接收文件", font=("Microsoft YaHei", 9), fg="#7f8c8d", bg='#f8f9fa')
receive_desc.pack(pady=(0, 15))
receive_button = tk.Button(
receive_card,
text="开始接收",
command=self.show_receive_screen,
font=("Microsoft YaHei", 11, "bold"),
bg="#2ecc71",
fg="white",
width=12,
height=2,
relief='flat',
cursor='hand2'
)
receive_button.pack()
# 底部信息
footer_frame = tk.Frame(self.main_frame, bg='white')
footer_frame.pack(side='bottom', pady=20)
footer_label = tk.Label(
footer_frame,
text="© 2024 蜗牛创造 - 让文件传输更简单",
font=("Microsoft YaHei", 9),
fg="#bdc3c7",
bg='white'
)
footer_label.pack()
def create_styled_button(self, parent, text, command, bg_color, width=10):
"""创建样式统一的按钮"""
return tk.Button(
parent,
text=text,
command=command,
font=("Microsoft YaHei", 10, "bold"),
bg=bg_color,
fg="white",
width=width,
relief='flat',
cursor='hand2',
padx=10,
pady=5
)
def show_send_screen(self):
"""显示发送界面"""
self.clear_frame()
# 标题栏
title_frame = tk.Frame(self.main_frame, bg='white')
title_frame.pack(fill='x', pady=(10, 20))
back_button = self.create_styled_button(title_frame, "← 返回", self.show_welcome_screen, "#95a5a6", 8)
back_button.pack(side='left')
title_label = tk.Label(
title_frame,
text="📤 文件发送",
font=("Microsoft YaHei", 16, "bold"),
fg="#2c3e50",
bg='white'
)
title_label.pack(side='left', padx=10)
# 输入卡片
input_card = tk.Frame(self.main_frame, bg='#f8f9fa', relief='raised', bd=1, padx=20, pady=20)
input_card.pack(fill='x', pady=(0, 15))
# 密钥输入
key_frame = tk.Frame(input_card, bg='#f8f9fa')
key_frame.pack(fill='x', pady=5)
tk.Label(key_frame, text="🔑 密钥:", font=("Microsoft YaHei", 10), bg='#f8f9fa').pack(side='left')
self.send_key_entry = tk.Entry(key_frame, font=("Microsoft YaHei", 10), width=40, relief='solid', bd=1)
self.send_key_entry.pack(side='left', padx=10)
# 文件选择
file_frame = tk.Frame(input_card, bg='#f8f9fa')
file_frame.pack(fill='x', pady=10)
tk.Label(file_frame, text="📁 文件路径:", font=("Microsoft YaHei", 10), bg='#f8f9fa').pack(side='left')
self.file_path_var = tk.StringVar()
file_entry = tk.Entry(file_frame, textvariable=self.file_path_var, font=("Microsoft YaHei", 10),
width=30, state='readonly', relief='solid', bd=1)
file_entry.pack(side='left', padx=10)
browse_button = self.create_styled_button(file_frame, "浏览文件", self.browse_file, "#8e44ad", 10)
browse_button.pack(side='left')
# 按钮组
button_frame = tk.Frame(self.main_frame, bg='white')
button_frame.pack(pady=15)
self.send_connect_button = self.create_styled_button(button_frame, "🔄 连接", self.start_send_connection, "#27ae60")
self.send_connect_button.pack(side='left', padx=5)
self.send_file_button = self.create_styled_button(button_frame, "🚀 发送文件", self.start_file_send, "#e74c3c")
self.send_file_button.pack(side='left', padx=5)
self.send_file_button.config(state='disabled')
self.send_stop_button = self.create_styled_button(button_frame, "⏹️ 停止", self.stop_send_connection, "#95a5a6")
self.send_stop_button.pack(side='left', padx=5)
self.send_stop_button.config(state='disabled')
# 状态显示
status_frame = tk.Frame(self.main_frame, bg='white')
status_frame.pack(fill='x', pady=5)
self.send_status_label = tk.Label(
status_frame,
text="📊 状态: 等待连接",
font=("Microsoft YaHei", 10),
fg="#7f8c8d",
bg='white'
)
self.send_status_label.pack()
# 输出区域
output_card = tk.Frame(self.main_frame, bg='#f8f9fa', relief='raised', bd=1, padx=15, pady=15)
output_card.pack(fill='both', expand=True, pady=(10, 0))
output_label = tk.Label(output_card, text="📋 发送日志:", font=("Microsoft YaHei", 10), bg='#f8f9fa')
output_label.pack(anchor='w')
self.send_output = scrolledtext.ScrolledText(
output_card,
height=12,
width=80,
font=("Consolas", 9),
state='disabled',
relief='solid',
bd=1,
bg='#ffffff'
)
self.send_output.pack(fill='both', expand=True, pady=(5, 0))
# 初始信息
self.append_send_output("等待输入密钥并选择文件...\n")
self.append_send_output("密钥格式应为: token|sk|psk|sern\n")
# 进程引用
self.send_frpc_process = None
self.send_p2p_process = None
self.is_send_running = False
def show_receive_screen(self):
"""显示接收界面"""
self.clear_frame()
# 标题栏
title_frame = tk.Frame(self.main_frame, bg='white')
title_frame.pack(fill='x', pady=(10, 20))
back_button = self.create_styled_button(title_frame, "← 返回", self.show_welcome_screen, "#95a5a6", 8)
back_button.pack(side='left')
title_label = tk.Label(
title_frame,
text="📥 文件接收",
font=("Microsoft YaHei", 16, "bold"),
fg="#2c3e50",
bg='white'
)
title_label.pack(side='left', padx=10)
# 输入卡片
input_card = tk.Frame(self.main_frame, bg='#f8f9fa', relief='raised', bd=1, padx=20, pady=20)
input_card.pack(fill='x', pady=(0, 15))
# 密钥输入
key_frame = tk.Frame(input_card, bg='#f8f9fa')
key_frame.pack(fill='x', pady=5)
tk.Label(key_frame, text="🔑 密钥:", font=("Microsoft YaHei", 10), bg='#f8f9fa').pack(side='left')
self.receive_key_entry = tk.Entry(key_frame, font=("Microsoft YaHei", 10), width=40, relief='solid', bd=1)
self.receive_key_entry.pack(side='left', padx=10)
# 保存路径选择
path_frame = tk.Frame(input_card, bg='#f8f9fa')
path_frame.pack(fill='x', pady=10)
tk.Label(path_frame, text="💾 保存路径:", font=("Microsoft YaHei", 10), bg='#f8f9fa').pack(side='left')
self.receive_path_var = tk.StringVar()
self.receive_path_var.set(".\\received_files") # 默认路径
path_entry = tk.Entry(path_frame, textvariable=self.receive_path_var, font=("Microsoft YaHei", 10),
width=30, relief='solid', bd=1)
path_entry.pack(side='left', padx=10)
browse_path_button = self.create_styled_button(path_frame, "浏览文件夹", self.browse_receive_path, "#8e44ad", 12)
browse_path_button.pack(side='left')
# 按钮组
button_frame = tk.Frame(self.main_frame, bg='white')
button_frame.pack(pady=15)
self.connect_button = self.create_styled_button(button_frame, "🔄 连接", self.start_frpc_connection, "#27ae60")
self.connect_button.pack(side='left', padx=5)
self.stop_button = self.create_styled_button(button_frame, "⏹️ 停止", self.stop_frpc_connection, "#e74c3c")
self.stop_button.pack(side='left', padx=5)
self.stop_button.config(state='disabled')
# 状态显示
status_frame = tk.Frame(self.main_frame, bg='white')
status_frame.pack(fill='x', pady=5)
self.status_label = tk.Label(
status_frame,
text="📊 状态: 等待连接",
font=("Microsoft YaHei", 10),
fg="#7f8c8d",
bg='white'
)
self.status_label.pack()
# 输出区域
output_card = tk.Frame(self.main_frame, bg='#f8f9fa', relief='raised', bd=1, padx=15, pady=15)
output_card.pack(fill='both', expand=True, pady=(10, 0))
output_label = tk.Label(output_card, text="📋 接收日志:", font=("Microsoft YaHei", 10), bg='#f8f9fa')
output_label.pack(anchor='w')
self.receive_output = scrolledtext.ScrolledText(
output_card,
height=12,
width=80,
font=("Consolas", 9),
state='disabled',
relief='solid',
bd=1,
bg='#ffffff'
)
self.receive_output.pack(fill='both', expand=True, pady=(5, 0))
# 初始信息
self.append_output("等待输入密钥并连接...\n")
self.append_output("密钥格式应为: token|sk|psk|sern\n")
self.append_output(f"文件将保存到: {self.receive_path_var.get()}\n")
# 进程引用
self.frpc_process = None
self.p2p_process = None
self.is_running = False
self.current_stage = "idle"
def browse_receive_path(self):
"""浏览选择接收文件保存路径"""
folder_path = filedialog.askdirectory(
title="选择文件保存目录",
initialdir="."
)
if folder_path:
self.receive_path_var.set(folder_path)
self.append_output(f"✅ 文件将保存到: {folder_path}\n")
def browse_file(self):
"""浏览选择要发送的文件"""
file_path = filedialog.askopenfilename(
title="选择要发送的文件",
filetypes=[
("所有文件", "*.*"),
("文本文件", "*.txt"),
("图片文件", "*.jpg *.png *.gif"),
("视频文件", "*.mp4 *.avi *.mov"),
("文档文件", "*.pdf *.doc *.docx")
]
)
if file_path:
self.file_path_var.set(file_path)
self.append_send_output(f"✅ 已选择文件: {file_path}\n")
def create_send_ini(self, token, sk, sern, bport):
"""创建send.ini配置文件"""
ini_content = f"""[common]
local_ip = 0.0.0.0
server_addr = 47.97.6.201
server_port = 7100
token = {token}
[xtcp_visitor]
type = xtcp
role = visitor
server_name = {sern}
sk = {sk}
bind_ip = 127.0.0.1
bind_port = 7001
"""
try:
with open('./send.ini', 'w', encoding='utf-8') as f:
f.write(ini_content)
self.append_send_output(f"配置文件 send.ini 创建成功\n")
return True
except Exception as e:
self.append_send_output(f"创建配置文件失败: {e}\n")
return False
def monitor_send_frpc_output(self):
"""监控发送NATCC输出"""
try:
for line in iter(self.send_frpc_process.stdout.readline, ''):
if not self.is_send_running:
break
if line:
self.append_send_output(f"[NATC] {line}")
except:
pass
def monitor_send_p2p_output(self):
"""监控发送P2P输出"""
try:
for line in iter(self.send_p2p_process.stdout.readline, ''):
if not self.is_send_running:
break
if line.strip():
self.append_send_output(f"[P2P] {line}")
# 进程结束后检查退出码
return_code = self.send_p2p_process.wait()
if self.is_send_running:
self.append_send_output(f"[P2P] 文件发送完成,退出码: {return_code}\n")
self.send_file_button.config(state='normal')
except Exception as e:
self.append_send_output(f"[P2P] 输出监控错误: {e}\n")
def execute_send_frpc(self):
"""执行发送NATCC命令"""
try:
self.update_send_status("正在启动NATC客户端...")
self.send_frpc_process = subprocess.Popen(
['.\\gc.exe', '-c', '.\\send.ini'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
encoding='utf-8',
errors='replace',
bufsize=1,
universal_newlines=True,
creationflags=subprocess.CREATE_NO_WINDOW # 不创建窗口
)
# 启动输出监控线程
output_thread = threading.Thread(target=self.monitor_send_frpc_output, daemon=True)
output_thread.start()
# 等待一段时间让NATCC建立连接
self.append_send_output("[NATC] 等待NATC连接建立...\n")
time.sleep(3)
# 检查NATCC进程是否还在运行
if self.send_frpc_process.poll() is not None:
self.append_send_output("[NATC] NATC客户端意外退出\n")
return
# 如果还在运行,启用发送文件按钮
if self.is_send_running:
self.append_send_output("[NATC] NATC连接已建立,可以发送文件\n")
self.send_file_button.config(state='normal')
self.update_send_status("就绪,可以发送文件")
except Exception as e:
self.append_send_output(f"[NATC] 执行错误: {e}\n")
def execute_send_file(self):
"""执行文件发送"""
try:
self.update_send_status("正在发送文件...")
file_path = self.file_path_var.get()
if not file_path or not os.path.exists(file_path):
self.append_send_output("[错误] 文件路径无效或文件不存在\n")
return
self.send_p2p_process = subprocess.Popen(
[
'.\\python.exe',
'.\\p2pfile.py',
'--mode', 'send',
'--path', file_path,
'--psk', self.send_psk
'--port', self.bport
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
encoding='gbk',
errors='replace',
bufsize=1,
universal_newlines=True,
creationflags=subprocess.CREATE_NO_WINDOW # 不创建窗口
)
self.append_send_output(f"[P2P] 开始发送文件: {os.path.basename(file_path)}\n")
# 启动输出监控线程
output_thread = threading.Thread(target=self.monitor_send_p2p_output, daemon=True)
output_thread.start()
except Exception as e:
self.append_send_output(f"[P2P] 执行错误: {e}\n")
def start_send_connection(self):
"""开始发送连接"""
key = self.send_key_entry.get().strip()
if not key:
messagebox.showwarning("输入错误", "请输入密钥")
return
# 解析密钥
if '|' not in key:
messagebox.showwarning("格式错误", "密钥格式应为: token|sk|psk|sern|bport")
return
parts = key.split('|')
if len(parts) < 4:
messagebox.showwarning("格式错误", "密钥格式应为: token|sk|psk|sern|bport")
return
token = parts[0].strip()
sk = parts[1].strip()
psk = parts[2].strip()
sern = parts[3].strip()
bport = parts[4].strip()
self.send_token = token
self.send_sk = sk
self.send_psk = psk
self.send_sern = sern
self.bport = bport
# 创建配置文件
if not self.create_send_ini(token, sk, sern, bport):
return
# 清空输出框
self.send_output.config(state='normal')
self.send_output.delete(1.0, tk.END)
self.send_output.config(state='disabled')
self.append_send_output(f"开始连接流程...\n")
self.append_send_output(f"Token: {token}\n")
self.append_send_output(f"SK: {sk}\n")
self.append_send_output(f"PSK: {psk}\n")
self.append_send_output(f"SERN: {sern}\n")
self.append_send_output(f"BPORT: {bport}\n")
self.append_send_output("-" * 50 + "\n")
# 禁用连接按钮,启用停止按钮
self.send_connect_button.config(state='disabled')
self.send_stop_button.config(state='normal')
# 设置运行标志
self.is_send_running = True
self.update_send_status("启动中...")
# 在新线程中执行NATCC
self.send_process_thread = threading.Thread(target=self.execute_send_frpc, daemon=True)
self.send_process_thread.start()
def start_file_send(self):
"""开始发送文件"""
if not self.file_path_var.get():
messagebox.showwarning("选择错误", "请先选择要发送的文件")
return
# 禁用发送按钮,避免重复点击
self.send_file_button.config(state='disabled')
# 在新线程中执行文件发送
send_thread = threading.Thread(target=self.execute_send_file, daemon=True)
send_thread.start()
def stop_send_connection(self):
"""停止发送连接"""
self.is_send_running = False
self.update_send_status("正在停止...")
# 停止NATCC进程
if self.send_frpc_process and self.send_frpc_process.poll() is None:
try:
self.send_frpc_process.terminate()
self.append_send_output("[NATC] 正在停止NATC客户端...\n")
except:
pass
# 停止P2P进程
if self.send_p2p_process and self.send_p2p_process.poll() is None:
try:
self.send_p2p_process.terminate()
self.append_send_output("[P2P] 正在停止文件发送...\n")
except:
pass
time.sleep(1)
self.send_connect_button.config(state='normal')
self.send_file_button.config(state='disabled')
self.send_stop_button.config(state='disabled')
self.update_send_status("已停止")
self.append_send_output("所有进程已停止\n")
def update_send_status(self, status):
"""更新发送状态标签"""
self.send_status_label.config(text=f"状态: {status}")
def append_send_output(self, message):
"""向发送输出框添加消息"""
self.send_output.config(state='normal')
self.send_output.insert(tk.END, message)
self.send_output.see(tk.END)
self.send_output.config(state='disabled')
def create_service_ini(self, token, sk, sern, bport):
"""创建service.ini配置文件"""
ini_content = f"""[common]
server_addr = 47.97.6.201
server_port = 7100
token = {token}
[{sern}]
type = xtcp
sk = {sk}
local_ip = 127.0.0.1
local_port = {bport}
"""
try:
with open('./service.ini', 'w', encoding='utf-8') as f:
f.write(ini_content)
self.append_output(f"配置文件 service.ini 创建成功\n")
return True
except Exception as e:
self.append_output(f"创建配置文件失败: {e}\n")
return False
def execute_frpc(self):
"""执行frpc命令"""
try:
self.current_stage = "frpc"
self.update_status("正在启动NATC客户端...")
self.frpc_process = subprocess.Popen(
['.\\gc.exe', '-c', '.\\service.ini'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
encoding='utf-8',
errors='replace',
bufsize=1,
universal_newlines=True,
creationflags=subprocess.CREATE_NO_WINDOW # 不创建窗口
)
# 启动输出监控线程
output_thread = threading.Thread(target=self.monitor_frpc_output, daemon=True)
output_thread.start()
# 等待一段时间让NATCC建立连接
self.append_output("[NATC] 等待NATC连接建立...\n")
time.sleep(3) # 等待3秒让NATCC建立连接
# 检查NATCC进程是否还在运行
if self.frpc_process.poll() is not None:
self.append_output("[NATC] NATC客户端意外退出\n")
return
# 如果还在运行,启动P2P
if self.is_running:
self.append_output("[NATC] NATC连接已建立,启动P2P接收器...\n")
self.execute_p2p_receiver()
except Exception as e:
self.append_output(f"[NATC] 执行错误: {e}\n")
def monitor_frpc_output(self):
"""监控NATCC输出"""
try:
for line in iter(self.frpc_process.stdout.readline, ''):
if not self.is_running:
break
if line:
self.append_output(f"[NATC] {line}")
except:
pass
def monitor_p2p_output(self):
"""监控P2P输出并检测进程结束"""
try:
for line in iter(self.p2p_process.stdout.readline, ''):
if not self.is_running:
break
if line.strip():
self.append_output(f"[P2P] {line}")
# 进程结束后检查退出码
return_code = self.p2p_process.wait()
if self.is_running:
self.append_output(f"[P2P] P2P接收器已停止,退出码: {return_code}\n")
except Exception as e:
self.append_output(f"[P2P] 输出监控错误: {e}\n")
def execute_p2p_receiver(self):
"""执行P2P文件接收器"""
try:
self.current_stage = "p2p"
self.update_status("正在启动P2P文件接收...")
# 获取用户选择的保存路径
save_path = self.receive_path_var.get().strip()
if not save_path:
save_path = ".\\received_files" # 默认路径
# 创建目录(如果不存在)
os.makedirs(save_path, exist_ok=True)
self.p2p_process = subprocess.Popen(
[
'.\\python.exe',
'.\\p2pfile.py',
'--mode', 'recv',
'--psk', self.current_psk,
'--outdir', save_path,
'--port', self.bport
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
encoding='gbk',
errors='replace',
bufsize=1,
universal_newlines=True,
creationflags=subprocess.CREATE_NO_WINDOW # 不创建窗口
)
self.append_output("[P2P] 启动P2P文件接收器...\n")
self.append_output(f"[P2P] 使用PSK: {self.current_psk}\n")
self.append_output(f"[P2P] 文件保存路径: {save_path}\n")
# 启动输出监控线程
output_thread = threading.Thread(target=self.monitor_p2p_output, daemon=True)
output_thread.start()
# 检查进程是否立即失败
time.sleep(1)
if self.p2p_process.poll() is not None:
self.append_output("[P2P] P2P接收器启动失败\n")
except Exception as e:
self.append_output(f"[P2P] 执行错误: {e}\n")
def start_frpc_connection(self):
"""开始NATC连接和P2P接收"""
key = self.receive_key_entry.get().strip()
if not key:
messagebox.showwarning("输入错误", "请输入密钥")
return
# 解析密钥
if '|' not in key:
messagebox.showwarning("格式错误", "密钥格式应为: token|sk|psk|sern")
return
parts = key.split('|')
if len(parts) < 4:
messagebox.showwarning("格式错误", "密钥格式应为: token|sk|psk|sern")
return
token = parts[0].strip()
sk = parts[1].strip()
psk = parts[2].strip()
sern = parts[3].strip()
bport = parts[4].strip()
self.current_token = token
self.current_sk = sk
self.current_psk = psk
self.current_sern = sern
self.bport = bport
# 获取保存路径并显示
save_path = self.receive_path_var.get()
self.append_output(f"📁 保存路径: {save_path}\n")
# 创建配置文件
if not self.create_service_ini(token, sk, sern, bport):
return
# 清空输出框
self.receive_output.config(state='normal')
self.receive_output.delete(1.0, tk.END)
self.receive_output.config(state='disabled')
self.append_output(f"开始连接流程...\n")
self.append_output(f"Token: {token}\n")
self.append_output(f"SK: {sk}\n")
self.append_output(f"PSK: {psk}\n")
self.append_output(f"SERN: {sern}\n")
self.append_output(f"保存路径: {save_path}\n")
self.append_output(f"port: {bport}\n")
self.append_output("-" * 50 + "\n")
# 禁用连接按钮,启用停止按钮
self.connect_button.config(state='disabled')
self.stop_button.config(state='normal')
# 设置运行标志
self.is_running = True
self.update_status("启动中...")
# 在新线程中执行
self.process_thread = threading.Thread(target=self.execute_frpc, daemon=True)
self.process_thread.start()
def stop_frpc_connection(self):
"""停止所有进程"""
self.is_running = False
self.update_status("正在停止...")
# 停止NATCC进程
if self.frpc_process and self.frpc_process.poll() is None:
try:
self.frpc_process.terminate()
self.append_output("[NATC] 正在停止NATC客户端...\n")
except:
pass
# 停止P2P进程
if self.p2p_process and self.p2p_process.poll() is None:
try:
self.p2p_process.terminate()
self.append_output("[P2P] 正在停止P2P接收器...\n")
except:
pass
time.sleep(1) # 给进程一些时间结束
self.connect_button.config(state='normal')
self.stop_button.config(state='disabled')
self.update_status("已停止")
self.append_output("所有进程已停止\n")
def update_status(self, status):
"""更新状态标签"""
self.status_label.config(text=f"状态: {status}")
def append_output(self, message):
"""向输出框添加消息"""
self.receive_output.config(state='normal')
self.receive_output.insert(tk.END, message)
self.receive_output.see(tk.END) # 自动滚动到底部
self.receive_output.config(state='disabled')
# 创建主窗口并运行程序
if __name__ == "__main__":
root = tk.Tk()
app = FileTransferApp(root)
root.mainloop()
Loading…
Cancel
Save