最近在杭州某安防企业实习被要求做了一个tcp协议通信的测试工具,还需要一直循环发送,单击按键暂停。记录一下开发过程中遇到的问题和踩到的坑
一开始没有提及循环发送的需求 于是只用了PyQt和socket库写成了单击发送的功能。
之后说需要循环发送 本来我寻思着无非是个while循环加个标志位的事情 结果事情万万没有我想的那么简单
简单的加上while循环之后发现程序直接卡死,根本无法更改控制循环的标志位
def tcp_connet(self):
file_num=1
count=0
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建一个客户端的socket对象
host = self.ip_line.text() # 设置服务端的ip地址
port = int(self.port_line.text()) # 设置端口
type = int(self.type_line.text())
client.connect((host, port)) # 连接服务端
sendmsg = self.creat_hex_msg(type)
client.send(sendmsg)
print(sendmsg)
while self.send_flag == 1: # while循环是为了保证能持续进行对话
file_num=1
count=0
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建一个客户端的socket对象
host = self.ip_line.text() # 设置服务端的ip地址
port = int(self.port_line.text()) # 设置端口
type = int(self.type_line.text())
client.connect((host, port)) # 连接服务端
sendmsg = self.creat_hex_msg(type)
client.send(sendmsg)
print(sendmsg)
msg = client.recv(1024) # 接收服务端返回的数据,需要解码
file_path = sys.argv[0]
index = file_path.rfind('/')
target_path = file_path[:index + 1] + str(file_num) + "data.txt"
f = open(file=target_path, mode='ab')
f.write(msg)
f.close()
hexstr = binascii.b2a_hex(msg)
hexstr = str(hexstr)[2:-1]
bufsize = self.string_to_int(hexstr[16:24]) // 1024
while count<bufsize:
count+=1
msg = client.recv(1024) # 接收服务端返回的数据,需要解码
f = open(file=target_path, mode='ab')
f.write(msg)
f.close()
file_num+=1
count=0
#client.close() # 关闭客户端
后来查询了一些资料 发现得开线程去解决这个问题。
这之间也踩过另一个坑
本来想着是把标志位的改变放进线程中
结果发现把tcp循环放在主线程里程序必定会卡死
需要把tcp放入线程中 主线程只有Ui显示
找到方法之后开始实际操作 实际操作中也遇到了不少问题
首先是遇到了不同类变量传递的问题 定义了两个类Mythread和Ui_MainWindow
打算在Ui里创建ip port等变量然后给Mythread直接调用 结果发现无法跨类访问变量 即使继承了也不行 之后便考虑了信号和槽发射信息的方法 具体实现如下
class Ui_MainWindow(QObject):
sin = pyqtSignal()
ip_sin = pyqtSignal(str)
port_sin = pyqtSignal(int)
type_sin = pyqtSignal(int)
def __init__(self):
super(Ui_MainWindow,self).__init__()
self.myThread1 = myThread()
self.sin.connect(self.myThread1.stop)
self.ip_sin.connect(self.myThread1.set_ip)
self.port_s