python實現簡單的TCPProxy 伺服器

來源:互聯網
上載者:User
本文執行個體講述了python實現簡單的TCPProxy 伺服器的方法,分享給大家供大家參考。

具體實現代碼如下:

# -*- coding: utf-8 -*-'''filename:rtcp.py@desc:利用python的socket連接埠轉寄,用於遠程維護如果串連不到遠程,會sleep 36s,最多嘗試200(即兩小時)@usage:./rtcp.py stream1 stream2stream為:l:port或c:host:portl:port表示監聽指定的本地連接埠c:host:port表示監聽遠程指定的連接埠@author: watercloud, zd, knownsec team@web: www.knownsec.com, blog.knownsec.com@date: 2009-7'''import socketimport sysimport threadingimport timestreams = [None, None] # 存放需要進行資料轉寄的兩個資料流(都是SocketObj對象)debug = 1 # 調試狀態 0 or 1def _usage(): print 'Usage: ./rtcp.py stream1 stream2\nstream : l:port or c:host:port'def _get_another_stream(num): ''' 從streams擷取另外一個流對象,如果當前為空白,則等待 ''' if num == 0: num = 1 elif num == 1: num = 0 else: raise "ERROR" while True: if streams[num] == 'quit':  print("can't connect to the target, quit now!")  sys.exit(1) if streams[num] != None:  return streams[num] else:  time.sleep(1)def _xstream(num, s1, s2): ''' 交換兩個流的資料 num為當前流編號,主要用於調試目的,區分兩個迴路狀態用。 ''' try: while True:  #注意,recv函數會阻塞,直到對端完全關閉(close後還需要一定時間才能關閉,最快關閉方法是shutdow)  buff = s1.recv(1024)  if debug > 0:  print num,"recv"  if len(buff) == 0: #對端關閉串連,讀不到資料  print num,"one closed"  break  s2.sendall(buff)  if debug > 0:  print num,"sendall" except : print num,"one connect closed." try: s1.shutdown(socket.SHUT_RDWR) s1.close() except: pass try: s2.shutdown(socket.SHUT_RDWR) s2.close() except: pass streams[0] = None streams[1] = None print num, "CLOSED"def _server(port, num): ''' 處理服務情況,num為流編號(第0號還是第1號) ''' srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.bind(('0.0.0.0', port)) srv.listen(1) while True: conn, addr = srv.accept() print "connected from:", addr streams[num] = conn # 放入本端流對象 s2 = _get_another_stream(num) # 擷取另一端流對象 _xstream(num, conn, s2)def _connect(host, port, num): ''' 處理串連,num為流編號(第0號還是第1號) @note: 如果串連不到遠程,會sleep 36s,最多嘗試200(即兩小時) ''' not_connet_time = 0 wait_time = 36 try_cnt = 199 while True: if not_connet_time > try_cnt:  streams[num] = 'quit'  print('not connected')  return None conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try:  conn.connect((host, port)) except Exception, e:  print ('can not connect %s:%s!' % (host, port))  not_connet_time += 1  time.sleep(wait_time)  continue print "connected to %s:%i" % (host, port) streams[num] = conn #放入本端流對象 s2 = _get_another_stream(num) #擷取另一端流對象 _xstream(num, conn, s2)if __name__ == '__main__': if len(sys.argv) != 3: _usage() sys.exit(1) tlist = [] # 線程列表,最終存放兩個線程對象 targv = [sys.argv[1], sys.argv[2] ] for i in [0, 1]: s = targv[i] # stream描述 c:ip:port 或 l:port sl = s.split(':') if len(sl) == 2 and (sl[0] == 'l' or sl[0] == 'L'): # l:port  t = threading.Thread(target=_server, args=(int(sl[1]), i))  tlist.append(t) elif len(sl) == 3 and (sl[0] == 'c' or sl[0] == 'C'): # c:host:port  t = threading.Thread(target=_connect, args=(sl[1], int(sl[2]), i))  tlist.append(t) else:  _usage()  sys.exit(1) for t in tlist: t.start() for t in tlist: t.join() sys.exit(0)

完整執行個體代碼點擊此處本站下載。

希望本文所述對大家的Python程式設計有所協助。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.