95 lines
3.0 KiB
Python
95 lines
3.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
import os
|
|
import json
|
|
import random
|
|
import time
|
|
import base64
|
|
import threading
|
|
from tornado import ioloop
|
|
from tornado import gen
|
|
from tornado.websocket import websocket_connect
|
|
from tornado.tcpclient import TCPClient
|
|
|
|
class ClientSide:
|
|
|
|
def __init__(self, local_ip, remote_ip):
|
|
self._local_ip = local_ip
|
|
self._remote_ip = remote_ip
|
|
self.local_conn = None
|
|
self.local_read_future = None
|
|
self.remote_conn = None
|
|
self.conn_hash = {}
|
|
|
|
@gen.coroutine
|
|
def co_localConnect(self, idx):
|
|
print(idx, flush=True)
|
|
[local_host, local_port] = self._local_ip.split(':')
|
|
local_conn = yield TCPClient().connect(local_host, local_port)
|
|
self.conn_hash[idx] = local_conn
|
|
self.sendRemoteMsg({
|
|
'cmd' : 'connectOk',
|
|
'remoteConnIdx' : idx,
|
|
})
|
|
while True:
|
|
try:
|
|
data = yield local_conn.read_until_close()
|
|
if data:
|
|
self.sendRemoteMsg({
|
|
'cmd' : 'forwardData',
|
|
'remoteConnIdx' : idx,
|
|
'data' : str(base64.b64encode(data))
|
|
})
|
|
break
|
|
except:
|
|
print('qqqqq', flush=True)
|
|
break
|
|
|
|
@gen.coroutine
|
|
def co_remoteConnect(self):
|
|
[remote_host, remote_port] = self._remote_ip.split(':')
|
|
url = 'ws://%s:%s/websocket' % (remote_host, remote_port)
|
|
self.remote_conn = yield websocket_connect(url)
|
|
data = ''
|
|
try:
|
|
while True:
|
|
data += yield self.remote_conn.read_message()
|
|
if not data:
|
|
continue
|
|
lines = data.split('\n')
|
|
if data[-1] == '\n':
|
|
data = lines[-1]
|
|
lines = lines[:-1]
|
|
for line in lines:
|
|
msg = json.loads(line)
|
|
self.dispatchRemoteMsg(msg)
|
|
except:
|
|
print('wwwwwwwwww', flush=True)
|
|
|
|
|
|
def dispatchRemoteMsg(self, msg):
|
|
if msg['cmd'] == 'connect':
|
|
ioloop.IOLoop.current().spawn_callback(self.co_localConnect, msg['remoteConnIdx'])
|
|
elif msg['cmd'] == 'socketClose':
|
|
pass
|
|
elif msg['cmd'] == 'forwardData':
|
|
if msg['remoteConnIdx'] in self.conn_hash:
|
|
conn = self.conn_hash[msg['remoteConnIdx']]
|
|
data = base64.b64decode(msg['data'][2:-1])
|
|
print(data, flush=True)
|
|
conn.write(data)
|
|
|
|
def sendRemoteMsg(self, msg):
|
|
data = json.dumps(msg) + '\n'
|
|
self.remote_conn.write_message(data)
|
|
|
|
@gen.coroutine
|
|
def co_connect(self):
|
|
# ioloop.IOLoop.current().spawn_callback(self.co_localConnect)
|
|
ioloop.IOLoop.current().spawn_callback(self.co_remoteConnect)
|
|
while True:
|
|
yield gen.sleep(0.1)
|
|
|
|
def run(self):
|
|
ioloop.IOLoop.current().run_sync(self.co_connect)
|
|
|