tools/scripts/proxy/cliside.py
aozhiwei dfc57226ea 1
2018-12-27 16:28:23 +08:00

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)