Skip to content

Commit bdc5d29

Browse files
committed
Optimized TCP implementation
1 parent 4257185 commit bdc5d29

File tree

1 file changed

+48
-60
lines changed

1 file changed

+48
-60
lines changed

proxy/tcp.py

+48-60
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import time
22
import socket
3-
import threading
3+
import select
4+
import uuid
5+
6+
from .ts3client import Ts3Client
7+
8+
"""tcp relay class
9+
10+
class for relaying the teamspeak3 tcp communication stuff
11+
"""
412

513

614
class Tcp():
@@ -12,65 +20,45 @@ def __init__(self, relayPort, remoteAddr, remotePort):
1220
self.socket.listen()
1321
self.remoteAddr = remoteAddr
1422
self.remotePort = remotePort
15-
self.clientList = dict()
16-
t = threading.Thread(target=self.get_from_server)
17-
t.start()
18-
19-
def get_from_server(self):
20-
while True:
21-
# send data from remote server to specific client
22-
for key in list(self.clientList):
23-
try:
24-
data = self.clientList[key]['rsocket'].recv(1024)
25-
self.clientList[key]['lastseen'] = time.time()
26-
self.clientList[key]['csocket'].send(data)
27-
except socket.error as msg:
28-
pass
29-
time.sleep(.025)
30-
31-
def get_from_client(self, conn, addr):
32-
while True:
33-
try:
34-
# if we see the client the first time
35-
if not addr in self.clientList:
36-
print('connected: ' + str(addr))
37-
rsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
38-
rsocket.connect((self.remoteAddr, self.remotePort))
39-
rsocket.setblocking(False)
40-
self.clientList[addr] = {
41-
'rsocket': rsocket,
42-
'csocket': conn,
43-
'lastseen': time.time()
44-
}
45-
data = conn.recv(1024)
46-
if len(data) != 0:
47-
self.clientList[addr]['rsocket'].send(data)
48-
else:
49-
self.clientList[addr]['rsocket'].close()
50-
del self.clientList[addr]
51-
print('disconnected: ' + str(addr))
52-
break
53-
except:
54-
try:
55-
self.clientList[addr]['rsocket'].close()
56-
except:
57-
pass
58-
try:
59-
self.clientList[addr]['csocket'].close()
60-
except:
61-
pass
62-
del self.clientList[addr]
63-
print('disconnected: ' + str(addr))
64-
break
65-
time.sleep(.025)
23+
self.clients = {}
6624

6725
def relay(self):
6826
while True:
69-
# get data from an connected client
70-
conn, addr = self.socket.accept()
71-
try:
72-
t = threading.Thread(
73-
target=self.get_from_client, args=(conn, addr))
74-
t.start()
75-
except:
76-
pass
27+
readable, writable, exceptional = select.select(list(self.clients.values()) + [self.socket], [], [], 1)
28+
for s in readable:
29+
# if ts3 server answers to a client or vice versa
30+
if isinstance(s, Ts3Client):
31+
try:
32+
data = s.socket.recv(4096)
33+
if len(data) != 0:
34+
self.clients[s.addr].socket.send(data)
35+
else:
36+
raise
37+
except:
38+
# get second socket from list
39+
addr = self.clients[s.addr].addr
40+
try:
41+
# close other socket
42+
self.clients[s.addr].socket.close()
43+
except:
44+
pass
45+
try:
46+
# close own socket, too
47+
self.clients[addr].socket.close()
48+
except:
49+
pass
50+
del self.clients[s.addr]
51+
del self.clients[addr]
52+
if isinstance(addr, tuple):
53+
print('disconnected', addr)
54+
else:
55+
print('disconnected', s.addr)
56+
else:
57+
conn, addr = s.accept()
58+
data = conn.recv(4096)
59+
print('connected', addr)
60+
tmpuid = str(uuid.uuid4())
61+
self.clients[addr] = Ts3Client(conn, tmpuid)
62+
self.clients[tmpuid] = Ts3Client(socket.socket(socket.AF_INET, socket.SOCK_STREAM), addr)
63+
self.clients[tmpuid].socket.connect((self.remoteAddr, self.remotePort))
64+
self.clients[tmpuid].socket.send(data)

0 commit comments

Comments
 (0)