-
Notifications
You must be signed in to change notification settings - Fork 117
/
tcp_logic.py
181 lines (170 loc) · 6.72 KB
/
tcp_logic.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
from PyQt5 import QtWidgets
import tcp_udp_web_ui
import socket
import threading
import sys
import stopThreading
import time
class TcpLogic(tcp_udp_web_ui.ToolsUi):
def __init__(self, num):
super(TcpLogic, self).__init__(num)
self.tcp_socket = None
self.sever_th = None
self.client_th = None
self.client_socket_list = list()
self.link = False # 用于标记是否开启了连接
def tcp_server_start(self):
"""
功能函数,TCP服务端开启的方法
:return: None
"""
self.tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 取消主动断开连接四次握手后的TIME_WAIT状态
self.tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 设定套接字为非阻塞式
self.tcp_socket.setblocking(False)
try:
port = int(self.lineEdit_port.text())
self.tcp_socket.bind(('', port))
except Exception as ret:
msg = '请检查端口号\n'
self.signal_write_msg.emit(msg)
else:
self.tcp_socket.listen()
self.sever_th = threading.Thread(target=self.tcp_server_concurrency)
self.sever_th.start()
msg = 'TCP服务端正在监听端口:%s\n' % str(port)
self.signal_write_msg.emit(msg)
def tcp_server_concurrency(self):
"""
功能函数,供创建线程的方法;
使用子线程用于监听并创建连接,使主线程可以继续运行,以免无响应
使用非阻塞式并发用于接收客户端消息,减少系统资源浪费,使软件轻量化
:return:None
"""
while True:
try:
client_socket, client_address = self.tcp_socket.accept()
except Exception as ret:
time.sleep(0.001)
else:
client_socket.setblocking(False)
# 将创建的客户端套接字存入列表,client_address为ip和端口的元组
self.client_socket_list.append((client_socket, client_address))
msg = 'TCP服务端已连接IP:%s端口:%s\n' % client_address
self.signal_write_msg.emit(msg)
# 轮询客户端套接字列表,接收数据
for client, address in self.client_socket_list:
try:
recv_msg = client.recv(1024)
except Exception as ret:
pass
else:
if recv_msg:
msg = recv_msg.decode('utf-8')
msg = '来自IP:{}端口:{}:\n{}\n'.format(address[0], address[1], msg)
self.signal_write_msg.emit(msg)
else:
client.close()
self.client_socket_list.remove((client, address))
def tcp_client_start(self):
"""
功能函数,TCP客户端连接其他服务端的方法
:return:
"""
self.tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
address = (str(self.lineEdit_ip_send.text()), int(self.lineEdit_port.text()))
except Exception as ret:
msg = '请检查目标IP,目标端口\n'
self.signal_write_msg.emit(msg)
else:
try:
msg = '正在连接目标服务器\n'
self.signal_write_msg.emit(msg)
self.tcp_socket.connect(address)
except Exception as ret:
msg = '无法连接目标服务器\n'
self.signal_write_msg.emit(msg)
else:
self.client_th = threading.Thread(target=self.tcp_client_concurrency, args=(address,))
self.client_th.start()
msg = 'TCP客户端已连接IP:%s端口:%s\n' % address
self.signal_write_msg.emit(msg)
def tcp_client_concurrency(self, address):
"""
功能函数,用于TCP客户端创建子线程的方法,阻塞式接收
:return:
"""
while True:
recv_msg = self.tcp_socket.recv(1024)
if recv_msg:
msg = recv_msg.decode('utf-8')
msg = '来自IP:{}端口:{}:\n{}\n'.format(address[0], address[1], msg)
self.signal_write_msg.emit(msg)
else:
self.tcp_socket.close()
self.reset()
msg = '从服务器断开连接\n'
self.signal_write_msg.emit(msg)
break
def tcp_send(self):
"""
功能函数,用于TCP服务端和TCP客户端发送消息
:return: None
"""
if self.link is False:
msg = '请选择服务,并点击连接网络\n'
self.signal_write_msg.emit(msg)
else:
try:
send_msg = (str(self.textEdit_send.toPlainText())).encode('utf-8')
if self.comboBox_tcp.currentIndex() == 0:
# 向所有连接的客户端发送消息
for client, address in self.client_socket_list:
client.send(send_msg)
msg = 'TCP服务端已发送\n'
self.signal_write_msg.emit(msg)
if self.comboBox_tcp.currentIndex() == 1:
self.tcp_socket.send(send_msg)
msg = 'TCP客户端已发送\n'
self.signal_write_msg.emit(msg)
except Exception as ret:
msg = '发送失败\n'
self.signal_write_msg.emit(msg)
def tcp_close(self):
"""
功能函数,关闭网络连接的方法
:return:
"""
if self.comboBox_tcp.currentIndex() == 0:
try:
for client, address in self.client_socket_list:
client.close()
self.tcp_socket.close()
if self.link is True:
msg = '已断开网络\n'
self.signal_write_msg.emit(msg)
except Exception as ret:
pass
if self.comboBox_tcp.currentIndex() == 1:
try:
self.tcp_socket.close()
if self.link is True:
msg = '已断开网络\n'
self.signal_write_msg.emit(msg)
except Exception as ret:
pass
try:
stopThreading.stop_thread(self.sever_th)
except Exception:
pass
try:
stopThreading.stop_thread(self.client_th)
except Exception:
pass
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ui = TcpLogic(1)
ui.show()
sys.exit(app.exec_())