功能是打开本机端口,映射到指定ip的端口

场景1本机:tomcat启动8080,通过本端口工具打开80,指向到tomcat的8080。请求本机80可以不加端口

场景2远端:访问本机80,可以访问到百度ip对应的80端口。

其他功能自行发掘。

读取与保存对应配置文件 json形式存储

配置文件保存到config.txt

环境依赖 qt5需要安装

制作exe可执行文件 先安装 pip3 install pyinstaller

pyinstaller -f -i icon.ico -w xx.py

没有icon.ico图标文件的可以删了 -i 参数 pyinstaller -f -w xx.py

# -*- coding: utf-8 -*-
# 制作本地可执行文件
# pyinstaller -f -i ico.ico -w port.py
import sys
import json
import socket,threading
import os
import re
import traceback
from pyqt5 import qtwidgets,qtcore
from pyqt5.qtwidgets import qapplication, qwidget, qtextbrowser, qmessagebox
from pyqt5.qtgui import qicon, qpixmap
# 图标文件
iconb = b'\x00\x00\x01\x00\x01\x00  \x00\x00\x01\x00 \x00\xa8\x10\x00\x00\x16\x00\x00\x00(\x00\x00\x00 \x00\x00\x00@\x00\x00\x00\x01\x00 \x00\x00\x00\x00\x00\x00\x10\x00\x00\xc3\x0e\x00\x00\xc3\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:od\x00;of\x00:of\x00:of\x00;of\x00;pf\x00;pf\x00;pf\x00;pf\x00:oe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;pe\x00;pe\x00;pf\x00;pf\x00:of\x02:of\x01;of\x00;pf\x00;pf\x02;oe\x01;pf\x00;pf\x00;pe\x00;pf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;pe\x00;pe\x04;pf";pfv:ofh;pg\t+=p\x00.au\x00;pg\x0f;pfp;pfq;pf\x1c;pe\x02;pe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;pf\x00;pfk;pf\xd0<qgo<od\x12\x19\x16\x15\x05\x1d#+\r\x1d")\x0c\x1a\x17\x16\x04=qf\x18;qg\x80;pf\xcc;pf1;pf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 /@\x00 0a\x003fz\x00=si\x1d8la\xbc-?r\x94 4i\x89!9r\xb5">y\xc4"=y\xc2!9p\xb1 4h\x81/bv\xa29mb\xab@vm\x0f5i]\x00!1b\x00(7g\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 /@\x00 .>\x00\x1e\'2\x07\x1f0ay$<u\xd4%gi\xff&py\xff&t\x80\xff\'w\x84\xff\'v\x84\xff&t\x7f\xff%ow\xff%ff\xff#;r\xc5\x1f/?g\x1e\x1d \x02!/>\x00!1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:pf\x00;pf\x00;pf\x00;pf\x00;pf\x00 0a\x00\x1f.>\x00\x1e)6\x0c!4h\x8d%gi\xf7(w\x85\xff)\\\x8c\xff)\\\x8c\xff)\\\x8c\xff)[\x8b\xff)[\x8b\xff)\\\x8b\xff)\\\x8c\xff)\\\x8c\xff)v\x82\xff&fd\xef%7in!&-\x03!0?\x00\x1f0@\x00;pf\x00;pf\x00;pf\x00;pf\x00;pf\x00\x00\x00\x00\x00\x00\x00\x00\x00;pf\x00;pf\x05;pf5:pf\x06:pf\x00\x1f0a\x000c\x9a\x00!3gu\'lp\xfd,_\x91\xff,`\x92\xff,_\x91\xff,_\x91\xff,`\x91\xff,`\x91\xff-`\x91\xff.a\x92\xff/b\x93\xff0c\x93\xff1d\x94\xff2c\x92\xff+kk\xf3 1bs"4h\x00\x161=\x00:pf\x00;pf\x0c;pf:;pf\x02;pf\x00\x00\x00\x00\x00\x00\x00\x00\x00;pf\x00;pf\r;pf\x8f;pf\x17;of\x00 0a\x00\x1e*6\x1c%b_\xd8.a\x93\xff/e\x98\xff/d\x98\xff-a\x92\xff/c\x95\xff2g\x9a\xff3g\x99\xff4h\x9a\xff5i\x9b\xff3e\x96\xff5g\x97\xff9l\x9d\xff:l\x9d\xff5d\x90\xff$<u\xb9\x1b"*\n 0@\x00;pf\x00;pf";pf\x98;pf\x07;pf\x00\x00\x00\x00\x00\x00\x00\x00\x00;pf\x00;pf\t;pf\x9c;pf#;pf\x00 0a\x00\x1f,;@)mp\xf53k\x9f\xff0c\x94\xff$b^\xff3cr\xff-as\xff(os\xff9n\xa0\xff7i\x98\xff(gd\xff4ds\xff1bs\xff,op\xff@r\xa1\xff<o\xa0\xff\'ec\xe0\x1d(3\x1d 0a\x00;pf\x00;pf9;pf\xa4;pf\x06;pf\x00\x00\x00\x00\x00\x00\x00\x00\x00;pf\x00;pf\x06;pf\xa8;pf=;pf\x00 0a\x00\x1f-<g+ot\xf98o\xa4\xff*d]\xff\x98\x98\x98\xff\xe5\xe5\xe4\xff\xd4\xd3\xd2\xffhlo\xff*kk\xff-d[\xff\x8f\x90\x90\xff\xe0\xdf\xdf\xff\xdc\xdb\xda\xffknq\xff4wy\xffbv\xa8\xff(hg\xe1\x1d\'3\x1e 0a\x00;pf\x00;pft;pf\x9b8ne\x01:of\x00\x00\x00\x00\x00;pf\x00;pf\x00:pe\x03;pf\xa7;pf^;pf\x00 0a\x00\x1e,:>-rx\xf45g\x98\xfft\\d\xff\xfa\xf9\xf8\xff\xf2\xf2\xf2\xffqqq\xff\xad\xad\xad\xff?cg\xffsuv\xff\x8d\x8d\x8c\xff\x98\x98\x98\xff\xff\xff\xff\xff\xd6\xd5\xd4\xff6hz\xffbv\xa9\xff(gf\xdf\x1c&2\x1d 0a\x00;pf\x00;pfz;pf\x86;pf\x00:qd\x00:rd\x009oe\x00;pf\x00;pf\x00;pf\x8b;pf\x87;pf\x00 0a\x00\x1d(4"+np\xe26h\x98\xff^dk\xff\xfd\xfc\xfc\xff\xf3\xf3\xf3\xff\x86\x86\x86\xff\xce\xce\xce\xff||{\xff\xb0\xb0\xb0\xff\xa6\xa6\xa6\xff\xa8\xa8\xa8\xff\xff\xff\xff\xff\xde\xdd\xdd\xff:jz\xffau\xa7\xff\'c`\xc5\x19\x1e%\r#4f\x009nd\x01;pf\xa1;pfv;pf\x00;lh\x00?at\x00;pf];pf\x13;pf\x00;pfp;pf\xb1:oe\x05*;n\x00\x17\x19\x1e\x08&a[\xb5;o\xa1\xff;m_\xff\xd3\xd1\xd0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfc\xfc\xfc\xffyyy\xff\x96\x96\x96\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xa0\xa0\xa0\xff:xv\xff<m\x9d\xff#8o\x8ee\x92\xd8\x009mc\x00;pf\x0f;pf\xc4;pfr;pf\x00;pf\x1e;pfn;pf\x97;pfj;pf\x00;pfh;pf\xd1;pf\x1b;pf\x00#7l\x00 2d`5`\x8b\xfc=j\x96\xffnw`\xff\xb9\xb8\xb8\xff\xd9\xd8\xd7\xff\x8a\x8b\x8c\xff2h]\xffap]\xff\xaf\xae\xae\xff\xda\xd9\xd8\xff\x9c\x9c\x9c\xffarb\xffj}\xaf\xff/uz\xef\x1f-<= 1b\x00;pf\x00;pf-;pf\xd6;pf1;pf\x00;pfb;pf\x80;pf`;pf\x99:od\x02;pf#;pf\xd9;pfe;pf\x00\x1f/?\x00\x1b$.\x10\'a[\xb6bw\xab\xffk{\xa9\xff?[v\xffdzp\xffcd\x85\xff_\x91\xc2\xffx\x86\xb3\xffb]x\xfff\\q\xffed\x82\xffw\x8a\xbb\xff=m\x9c\xff#:p\x93\x15\x16\x18\x04\x1f.?\x00;pf\x00;pf_;pf\xce;oe\x13:pf\x0b;pf\xa8;pff;pf\x1a;pf\xbb;pfd;pf\x05;pf\xbc;pf\x88;pf\x00;pf\x00/bv\x00\x1c*8-*ih\xd1h~\xb3\xffb\x9a\xd1\xffh\x9c\xd0\xffk\x9f\xd3\xffk\x9e\xd1\xffl\x9f\xd3\xffm\xa1\xd3\xffl\x9f\xd2\xffe\x9c\xd2\xffct\xa5\xff&@z\xb9\x1a$1\x181dx\x00;pf\x00;oj\x00;pf\xa3;pf\xa3<pg\x00;pf\\;pf\xaf;pf\r;pf\x00;pfp;pf\xb9;pf\x0f;pft;pf\xdf;pfi;pfk;pf=>tj!$5fp\'c_\xfd>k\x99\xffx\x8e\xc4\xffg\x9d\xd4\xffl\xa2\xd7\xffm\xa2\xd8\xffg\x9d\xd3\xffv\x8b\xbf\xff9d\x8f\xff%>x\xf2\'7ht>tj$;pf@;pfl;pft;pf\xe5;pfw;pf\x1c;pf\xc7;pfw;pf\x00;pf\x00;pe\x14;pf\xbf;pf\x87;pf\x1e;pf\xa4;pf\xd9;pf\xdf;pf\xe5;qg\xdd2fz\xe4(jk\xfe+sz\xff-ps\xff6]\x85\xff;d\x8d\xff;d\x8d\xff5[\x82\xff/rt\xff-v~\xff(ge\xfb6j_\xe0;pf\xdf;pf\xe4;pf\xdf;pf\xd7;pf\x96:pf\x1b;pf\xa0;pf\xac;pe\n;pf\x00;pe\x00;pf\x00;pfb;pf\xdd;pfj;pe\x06;pf\x16;pf\';pfj<qgj3ey\xa2+mn\xf88p\xa6\xff<p\xa2\xff;j\x98\xff:d\x8e\xff<f\x90\xff@o\x9b\xffew\xa7\xff9o\xa3\xff)ea\xf07j^\x96;pff;pfd;pf$;pf\x14:oe\x08;pf\x80;pf\xd6;pf.;pf\x00;pf\x00;qf\x00;of\x00=uf\x00;pfh;pf\xe4;pf\x97;pf\x88;pf\xac;pf\xc6;pf\xd78la\xea*b[\xfe:p\xa4\xffk\x82\xb7\xffp\x85\xb9\xffr\x87\xba\xfft\x88\xba\xffv\x89\xbb\xffp\x86\xb9\xff6h\x97\xff+?u\xfd;od\xe6;pf\xd5;pf\xc3;pf\xa8;pf\x85;pf\xa0;pf\xe0;pfp;pf\x00;pe\x00:pe\x00;pf\x00;pf\x00;pf\x00;pf\x02;pff;pf\xc1;pf\xbb;pf\x9e;pf~1cw\x8f(?v\xe9$@\\\xff0x\x80\xffk\x85\xbe\xff]\x92\xc6\xffb\x95\xc6\xffd\x96\xc7\xffa\x94\xc7\xffj\x82\xb9\xff/ru\xff)d_\xff.cy\xe04g[\x88;pf\x81;pf\xa3;pf\xbd;pf\xbd;pfu7k^\x00;pe\x00;pf\x00;pf\x00;pf\x0c:of\x0f;pf\x00;pf\x00?of\x00;pf\t;pf\x06\x1d,<\x00\x1e-=8#?[\xd7)v\x82\xff*\\\x8c\xff\'jl\xff6b\x8e\xffp\x8a\xc4\xffa\x99\xd0\xffb\x99\xd0\xffq\x89\xbf\xff8_\x86\xff0tw\xff4d\x93\xff2\\\x84\xff%?y\xca\x1c+:)\x01\r\x18\x00;pf\x07;pf\x08;pe\x00;pe\x00;pf\x00;pf\x0f;pf\x07;pf5;pf\x88;pf\x0b;pf\x00:pf\x00:pe\x00*<o\x00\x1a\x1e%\x07#;s\xb0-\\\x8a\xff1f\x99\xff2f\x99\xff2d\x95\xff/ty\xff5x|\xff=f\x8f\xff>f\x8e\xff8z{\xff7]\x82\xff<m\x9d\xff>p\x9f\xff>p\xa0\xff-z\x85\xff"7m\x98\x01\x00\x00\x013f[\x00:pf\x00;qg\x00;pf\x00;pf\x15;pf\x8a:pf\x1e;pe\x07;pf\x96;pf~:oe\x04;pf\x00;pf\x00%6h\x00\x19",\x18&c`\xdb4j\x9e\xff:o\xa3\xff;p\xa4\xff=r\xa5\xff>r\xa5\xff=m\x9b\xff<f\x8f\xff>h\x91\xffbq\x9f\xffew\xa8\xfffx\xa9\xffhy\xa9\xfffy\xa9\xff4h\x9a\xff%a]\xb8\x00\x00\x00\x03*<o\x00;pf\x00;pf\x00:pf\x0b;pf\x95;pf\x81:pg\x01;pf\x00;pf%;pf\xc4;pf\x83;pf\x0b;pf\x00nh\x7f\x021btn)fd\xed8p\xa6\xffby\xad\xffez\xae\xfff{\xaf\xffh|\xaf\xffi~\xb0\xffj\x7f\xb2\xffl\x80\xb2\xffm\x80\xb2\xffn\x81\xb2\xffp\x82\xb3\xffq\x83\xb3\xffn\x81\xb2\xff8m\xa1\xff)c^\xd77i\\8tq\x8c\x00;pf\x00;pf\x12;pf\x98;pf\xb8;pf\x17;pf\x00<tg\x00;pf\x00;pf<;pf\xd3;pf\xa8;pfk;pf\x9a:nc\xe6+d^\xf29p\xa6\xffi\x81\xb7\xffn\x84\xb8\xffo\x85\xb9\xffq\x86\xb9\xffr\x87\xba\xffs\x88\xba\xffu\x89\xbb\xffv\x8a\xbb\xffw\x8a\xbc\xffy\x8b\xbc\xff[\x8c\xbd\xffo\x85\xb9\xff7k\x9d\xff,by\xf1;oe\xe2;pf\x8b;pfl;pf\xb8;pf\xc2;pf\';pf\x00;pf\x00:of\x00:pe\x00;of\x00;pf1;pf\xb8;pf\xec;pf\xc7<qgz$6is3`\x8b\xfdg\x84\xbe\xffv\x8d\xc2\xffy\x8e\xc3\xffz\x8f\xc3\xff[\x90\xc3\xff\\\x91\xc4\xff]\x91\xc4\xff_\x92\xc5\xff`\x93\xc5\xffb\x95\xc6\xff_\x93\xc5\xffg\x83\xbc\xff0x\x80\xf6%6h`<qgg;pf\xd0;pf\xeb;pf\xaa;pf";pf\x00<qh\x00;of\x00\x00\x00\x00\x00;pe\x00:rd\x00;pf\x00;pf\x11;pf;;pf\x143g[\x00\x1a$/\x11\'a[\xb6<q\xa4\xffp\x8d\xc8\xff_\x96\xcc\xffc\x98\xcd\xffd\x99\xcd\xffe\x9a\xce\xffg\x9b\xce\xffh\x9b\xce\xffi\x9c\xcf\xfff\x9a\xce\xffq\x8d\xc8\xff9k\x9c\xff%<t\x9d\x13\x18\x1f\x075i_\x00;pf\x1a;pf:;pf\x0b;pf\x00;qg\x00:od\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;qe\x00;pf\x00;pf\x00;pf\x00;pf\x00%6h\x00 /@\x00\x1e*9$(c^\xbb;m\x9e\xffo\x8c\xc9\xff_\x9a\xd4\xffh\x9f\xd6\xffk\xa1\xd6\xffl\xa2\xd7\xffj\xa1\xd7\xffa\x9b\xd4\xffn\x89\xc5\xff8f\x94\xfd\'?x\xa7\x1d(5\x19\x1f.>\x00\x00\x00\x00\x00;pf\x00;pf\x00;pf\x00;pf\x00;pf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f0a\x00"4g\x00 0@\x00\x1c\'3\x18$8n\x81/rv\xda<l\x9c\xfaf~\xb5\xffm\x88\xc1\xffm\x87\xc0\xffe{\xb1\xff:h\x96\xf8-no\xd1"5io\x1a#.\x0e\x1f.>\x00 0b\x00\x1f0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 0a\x00 0a\x00\x1f.>\x00\x8b\xff\xff\x00\x1b%1% 1cf%<t\x96(b\\\xb2(b\\\xaf$:q\x91 0@\\\x1a#.\x1d+lj\x00\x1f.>\x00 0a\x00 0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xe0\x07\xff\xff\x80\x01\xff\xff\x80\x01\xff\xff\x80\x01\xff\xfe\x00\x00\x7f\xfe\x00\x00\x7f\x80\x00\x00\x01\x80\x00\x00\x01\x80\x00\x00\x01\x80\x00\x00\x01\x80\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x01\xc0\x00\x00\x03\xfe\x00\x00\x7f\xff\x00\x00\xff'
class ui_mainwindow(qwidget):
def setupui(self,mainwindow):
mainwindow.setobjectname("mainwindow")
self.centralwidget = qtwidgets.qwidget(mainwindow)
self.centralwidget.setobjectname("centralwidget")
mainwindow.setcentralwidget(self.centralwidget)
# self.setgeometry(300, 300, 300, 220)
# 固定窗口大小
self.setfixedsize(360, 360)
# self.setwindowtitle('端口映射')
if os.path.exists('1ico.ico'):
self.setwindowicon(qicon('ico.ico'))
else:
icon = qpixmap()
icon.loadfromdata(iconb)
self.setwindowicon(qicon(icon))
# 标签
self.label1 = qtwidgets.qlabel(self.centralwidget)
self.label1.setgeometry(qtcore.qrect(20, 20, 80, 20))
self.label2 = qtwidgets.qlabel(self.centralwidget)
self.label2.setgeometry(qtcore.qrect(20, 50, 80, 20))
self.label3 = qtwidgets.qlabel(self.centralwidget)
self.label3.setgeometry(qtcore.qrect(20, 80, 80, 20))
self.input1 = qtwidgets.qlineedit(self.centralwidget)
self.input1.setgeometry(qtcore.qrect(120, 20, 80, 22))
self.input1.setobjectname("input1")
self.input2 = qtwidgets.qlineedit(self.centralwidget)
self.input2.setgeometry(qtcore.qrect(120, 50, 200, 22))
self.input2.setobjectname("input2")
self.input3 = qtwidgets.qlineedit(self.centralwidget)
self.input3.setgeometry(qtcore.qrect(120, 80, 80, 22))
self.input3.setobjectname("input3")
# 放置按钮
self.pushbutton = qtwidgets.qpushbutton(self.centralwidget)
self.pushbutton.setgeometry(qtcore.qrect(120, 110, 80, 25))
self.stopbutton = qtwidgets.qpushbutton(self.centralwidget)
self.stopbutton.setgeometry(qtcore.qrect(220, 110, 80, 25))
self.stopbutton.setenabled(false)
self.savebutton = qtwidgets.qpushbutton(self.centralwidget)
self.savebutton.setgeometry(qtcore.qrect(220, 20, 45, 25))
self.loadbutton = qtwidgets.qpushbutton(self.centralwidget)
self.loadbutton.setgeometry(qtcore.qrect(270, 20, 45, 25))
self.text_browser = qtextbrowser(self.centralwidget)
self.text_browser.setgeometry(qtcore.qrect(20, 150, 320, 190))
self.retranslateui(mqt)
qtcore.qmetaobject.connectslotsbyname(mainwindow)
def retranslateui(self, mainwindow):
_translate = qtcore.qcoreapplication.translate
self.setwindowtitle(_translate("mainwindow", "端口映射"))
self.label1.settext(_translate("mainwindow", "本机端口:"))
self.label2.settext(_translate("mainwindow", "目标ip:"))
self.label3.settext(_translate("mainwindow", "目标端口:"))
self.pushbutton.settext(_translate("mainwindow", "开始"))
self.savebutton.settext(_translate("mainwindow", "保存"))
self.loadbutton.settext(_translate("mainwindow", "读取"))
self.stopbutton.settext(_translate("mainwindow", "停止"))
class pipethread(threading.thread):
def __init__(self, source, target):
threading.thread.__init__(self,daemon=true)
self.source = source
self.target = target
def run(self):
while true:
try:
data = self.source.recv(1024)
if not data: break
self.target.send(data)
except:
print("通道退出...")
break
# 本地与目标ip端口建立通道
sockarr = []
# 是否是运行状态 开始/停止
isrunning = true
# 本地绑定端口,停止的时候需要释放本地端口
bindarr = []
class forwarding(threading.thread):
def __init__(self, port, targethost, targetport,targettxt):
threading.thread.__init__(self,daemon=true)
self.targethost = targethost
self.targetport = targetport
self.targettxt = targettxt
self.sock = socket.socket(socket.af_inet, socket.sock_stream)
self.sock.bind(('0.0.0.0', port))
self.sock.listen(10)
global bindarr
bindarr.append(self.sock)
def run(self):
while true:
try:
client_fd, addr = self.sock.accept()
except exception as e:
print("forwarding exception")
break
print("try connect...")
global isrunning
if not isrunning:
print("停止运行")
break
print("connecting...")
global sockarr
target_fd = socket.socket(socket.af_inet, socket.sock_stream)
target_fd.connect((self.targethost, self.targetport))
sockarr.append(client_fd)
sockarr.append(target_fd)
self.targettxt.append('new connect')
# two direct pipe
thread_1 = pipethread(target_fd, client_fd)
thread_1.start()
thread_2 = pipethread(client_fd, target_fd)
thread_2.start()
print("connected")
def stop(self):
try:
global sockarr
global bindarr
for sock in sockarr:
print("关闭sock")
sock.close()
sockarr = []
except exception as e:
print("关闭线程异常")
try:
for bind in bindarr:
print("关闭bind本地端口")
bind.close()
bindarr = []
except exception as e:
print("关闭bind本地端口异常")
configfile = "config.txt"
thread0 = none
class mqt(qtwidgets.qmainwindow, ui_mainwindow):
def __init__(self):
super(mqt,self).__init__()
self.setupui(self)
self.pushbutton.clicked.connect(self.run)
self.savebutton.clicked.connect(self.save)
self.loadbutton.clicked.connect(self.load)
self.stopbutton.clicked.connect(self.stop)
# 加载本地配置文件
self.load()
def stop(self):
print("stop")
global isrunning
isrunning = false
global thread0
thread0.stop()
self.pushbutton.setenabled(true)
self.stopbutton.setenabled(false)
self.text_browser.append("停止")
def save(self):
tx1 = self.input1.text().strip()
tx2 = self.input2.text().strip()
tx3 = self.input3.text().strip()
if tx1=='' or tx2=='' or tx3=='':
self.text_browser.append("保存失败:配置信息不能为空")
return
arr = []
arr.append(tx1)
arr.append(tx2)
arr.append(tx3)
savejson = json.dumps(arr)
with open(configfile,"w", encoding='utf-8', errors="strict") as f:
f.write(savejson)
self.text_browser.append("保存成功:{}".format(savejson))
self.text_browser.append("文件名:{}".format(configfile))
def load(self):
if os.path.exists(configfile):
try:
with open(configfile, 'r', encoding='utf-8', errors="strict") as f:
text = f.read()
arr = json.loads(text)
if len(arr)==3:
self.input1.settext(arr[0])
self.input2.settext(arr[1])
self.input3.settext(arr[2])
self.text_browser.append("读取成功:{}".format(text))
else:
self.text_browser.append("读取异常:{}".format(text))
self.text_browser.append("文件名:{}".format(configfile))
except exception as e:
self.text_browser.append("读取异常")
self.text_browser.append("文件名:{}".format(configfile))
print("读取配置文件失败:")
print(e)
traceback.print_exc()
else:
self.text_browser.append("配置文件不存在")
self.text_browser.append("文件名:{}".format(configfile))
# 定义槽函数
def run(self):
print("执行了run")
global isrunning
try:
# 获取输入框
tx1 = self.input1.text().strip()
tx2 = self.input2.text().strip()
tx3 = self.input3.text().strip()
numre = re.compile(r"[\d]+")
ipre = re.compile(r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")
comre = re.compile(r"[.\w-]*(:\d{,8})")
if not numre.match(tx1) or not (int(tx1)>0 and int(tx1)<65536):
qmessagebox.warning(none, "错误", "本机端口需要是数字,范围是 1-65535", qmessagebox.yes)
return
if not numre.match(tx3) or not (int(tx3)>0 and int(tx3)<65536):
qmessagebox.warning(none, "错误", "目标端口需要是数字,范围是 1-65535", qmessagebox.yes)
return
if not (comre.match(tx2) or ipre.match(tx2)):
qmessagebox.warning(none, "错误", "目标ip格式异常。", qmessagebox.yes )
return
# 校验完成
print('starting...')
port = int(tx1)
targethost = tx2
targetport = int(tx3)
print('localhost:{} => {}:{}'.format(port,targethost,targetport))
self.text_browser.settext('localhost:{} => {}:{}'.format(port,targethost,targetport))
# sys.stdout = open('forwaring.log', 'w')
self.pushbutton.setenabled(false)
self.stopbutton.setenabled(true)
global thread0
thread0 = forwarding(port, targethost, targetport,self.text_browser)
thread0.start()
isrunning = true
except exception as e:
isrunning = false
self.pushbutton.setenabled(true)
self.stopbutton.setenabled(false)
print("失败:")
print(e)
traceback.print_exc()
if __name__ == '__main__':
app = qapplication(sys.argv)
win = mqt()
win.show()
sys.exit(app.exec_())

到此这篇关于python3 qt5 端口转发工具的文章就介绍到这了,更多相关python3 qt5 端口转发内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!