from socket import * import sys, traceback, time from urllib import urlopen from thread import start_new_thread from Queue import Queue, Empty URL = 'http://snake.cs.uni-duesseldorf.de/' #URL = 'http://127.0.0.1:8000/' def exchange(path, retry=True): global timestamp timestamp += 1 delay = 1 while True: try: f = urlopen('%s%x%s' % (URL, timestamp, path)) data = f.read() assert data.startswith('cHs2') return data[4:] except KeyboardInterrupt: raise except: print '-'*60 traceback.print_exc() print '-'*60 if not retry: break if delay > 30: print "Giving up, sorry" sys.exit(1) print 'Retrying in %s seconds...' % delay time.sleep(delay) delay += 1 timestamp = 0 localport, remotehost, remoteport = sys.argv[1].split(':') localport = int(localport) remoteport = int(remoteport) assert '/' not in remotehost s = socket(AF_INET, SOCK_STREAM) s.bind(('', localport)) s.listen(1) print "Listening from connexion on %s..." % (s.getsockname(),) t, addr = s.accept() print "Connected by", addr f = open('/dev/urandom', 'rb') key = f.read(8).encode('base64').replace('\n', '').replace('=', '').replace('/', '-') f.close() result = exchange('/connect/%s/%s/%d' % (key, remotehost, remoteport)) assert result == ":-) connect\n", "connexion failed:\n%s" % (result,) def socket_reader(): try: while True: inqueue.put(t.recv(140)) except error: inqueue.put('') print "Closed socket_reader()" def socket_writer(): try: while True: item = outqueue.get() if item is None: break t.sendall(item) except error: print "Closed socket_writer()" inqueue = Queue() outqueue = Queue() start_new_thread(socket_reader, ()) start_new_thread(socket_writer, ()) delay = 0.0 try: while True: try: if delay > 0.0: data = inqueue.get(timeout=delay) else: data = inqueue.get(block=False) if data == '': break # connexion closed except Empty: data = '' if data: data = data.encode('base64').replace('\n', '').replace('=', '') data = exchange('/wr/%s/0/%s' % (key, data)) delay = 0.0 else: data = exchange('/r/%s/0.2' % (key,)) if not data: delay = min(10.0, (delay + 0.1) * 1.5) continue delay *= 0.1 data = data.decode('base64') if data: outqueue.put(data) finally: exchange('/close/%s' % (key,), retry=False) outqueue.put(None)