# -*- 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)