python实现简单的TCP代理服务器


Posted in Python onOctober 08, 2014

本文实例讲述了python实现简单的TCP代理服务器的方法,分享给大家供大家参考。

具体实现代码如下:

# -*- coding: utf-8 -*-

'''
filename:rtcp.py
@desc:
利用python的socket端口转发,用于远程维护
如果连接不到远程,会sleep 36s,最多尝试200(即两小时)

@usage:
./rtcp.py stream1 stream2
stream为:l:port或c:host:port
l:port表示监听指定的本地端口
c:host:port表示监听远程指定的端口

@author: watercloud, zd, knownsec team
@web: www.knownsec.com, blog.knownsec.com
@date: 2009-7
'''

import socket
import sys
import threading
import time

streams = [None, None] # 存放需要进行数据转发的两个数据流(都是SocketObj对象)
debug = 1 # 调试状态 0 or 1

def _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程序设计有所帮助。

Python 相关文章推荐
python使用在线API查询IP对应的地理位置信息实例
Jun 01 Python
Python实现将绝对URL替换成相对URL的方法
Jun 28 Python
13个最常用的Python深度学习库介绍
Oct 28 Python
Pyinstaller将py打包成exe的实例
Mar 31 Python
python itchat给指定联系人发消息的方法
Jun 11 Python
python射线法判断一个点在图形区域内外
Jun 28 Python
python如何实现数据的线性拟合
Jul 19 Python
pandas的to_datetime时间转换使用及学习心得
Aug 11 Python
Spring http服务远程调用实现过程解析
Jun 11 Python
Pycharm2020.1安装中文语言插件的详细教程(不需要汉化)
Aug 07 Python
Python collections.deque双边队列原理详解
Oct 05 Python
Python机器学习之逻辑回归
May 11 Python
python操作CouchDB的方法
Oct 08 #Python
python基于queue和threading实现多线程下载实例
Oct 08 #Python
python实现封装得到virustotal扫描结果
Oct 05 #Python
python解析xml文件操作实例
Oct 05 #Python
python写xml文件的操作实例
Oct 05 #Python
python实现上传样本到virustotal并查询扫描信息的方法
Oct 05 #Python
python实现计算资源图标crc值的方法
Oct 05 #Python
You might like
如何获知PHP程序占用多少内存(memory_get_usage)
2012/09/23 PHP
如何使用php绘制在图片上的正余弦曲线
2013/06/08 PHP
查找php配置文件php.ini所在路径的二种方法
2014/05/26 PHP
ThinkPHP之R方法实例详解
2014/06/20 PHP
ThinkPHP模板范围判断输出In标签与Range标签用法详解
2014/06/30 PHP
php树型类实例
2014/12/05 PHP
基于php实现七牛抓取远程图片
2015/12/01 PHP
document.onreadystatechange事件的用法分析
2009/10/17 Javascript
javascript 鼠标拖动图标技术
2010/02/07 Javascript
解析Jquery中如何把一段html代码动态写入到DIV中(实例说明)
2013/07/09 Javascript
页面向下滚动ajax获取数据的实现方法(兼容手机)
2016/05/24 Javascript
Ionic默认的Tabs模板使用实例
2016/08/29 Javascript
jQuery弹出遮罩层效果完整示例
2016/09/13 Javascript
JavaScript 保护变量不被随意修改的实现代码
2017/09/27 Javascript
快速解决vue-cli在ie9+中无效的问题
2018/09/04 Javascript
webpack结合express实现自动刷新的方法
2019/05/07 Javascript
python面向对象_详谈类的继承与方法的重载
2017/06/07 Python
python计算auc指标实例
2017/07/13 Python
详解appium+python 启动一个app步骤
2017/12/20 Python
Python字典操作详细介绍及字典内建方法分享
2018/01/04 Python
Flask使用Pyecharts在单个页面展示多个图表的方法
2019/08/05 Python
程序员的七夕用30行代码让Python化身表白神器
2019/08/07 Python
phonegap常用事件总结(必看篇)
2017/03/31 HTML / CSS
Reebok官方旗舰店:美国知名健身品牌锐步
2019/01/07 全球购物
Java语言的优势
2015/01/10 面试题
关于礼仪的演讲稿
2014/01/04 职场文书
《理想》教学反思
2014/02/17 职场文书
企业文化演讲稿
2014/05/20 职场文书
迎国庆横幅标语
2014/10/08 职场文书
中国梦宣传标语口号
2015/12/26 职场文书
亲情作文之母爱
2019/09/25 职场文书
导游词之日月潭
2019/11/05 职场文书
Python Django 后台管理之后台模型属性详解
2021/04/25 Python
粗暴解决CUDA out of memory的问题
2021/05/22 Python
Python爬虫中urllib3与urllib的区别是什么
2021/07/21 Python
微信小程序 根据不同用户切换不同TabBar
2022/04/21 Javascript