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代码公开揭秘!
Mar 08 Python
PYQT5设置textEdit自动滚屏的方法
Jun 14 Python
django-rest-framework解析请求参数过程详解
Jul 18 Python
Python3 无重复字符的最长子串的实现
Oct 08 Python
Python实现数值积分方式
Nov 20 Python
tensorflow-gpu安装的常见问题及解决方案
Jan 20 Python
基于keras输出中间层结果的2种实现方式
Jan 24 Python
Python实现Word表格转成Excel表格的示例代码
Apr 16 Python
python实现Oracle查询分组的方法示例
Apr 30 Python
Python可以实现栈的结构吗
May 27 Python
利用Vscode进行Python开发环境配置的步骤
Jun 22 Python
基于Python的接口自动化unittest测试框架和ddt数据驱动详解
Jan 27 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系统命令函数使用分析
2013/07/05 PHP
php function用法如何递归及return和echo区别
2014/03/07 PHP
php+MySQL判断update语句是否执行成功的方法
2014/08/28 PHP
Laravel给生产环境添加监听事件(SQL日志监听)
2017/06/19 PHP
JavaScript的目的分析
2007/01/05 Javascript
JS加ASP二级域名转向的代码
2007/05/17 Javascript
jscript之Read an Excel Spreadsheet
2007/06/13 Javascript
div层的移动及性能优化
2010/11/16 Javascript
如何设置iframe高度自适应在跨域情况下的可用方法
2013/09/06 Javascript
AngularJS入门知识之MVW类框架的编程思想探讨
2014/12/08 Javascript
原生JavaScript实现滚动条效果
2020/03/24 Javascript
JavaScript知识点总结(十)之this关键字
2016/05/31 Javascript
基于jquery插件编写countdown计时器
2016/06/12 Javascript
全面解析Javascript无限添加QQ好友原理
2016/06/15 Javascript
JavaScript实现清空(重置)文件类型INPUT元素值的方法
2016/11/17 Javascript
写给小白看的JavaScript异步
2017/11/29 Javascript
JavaScript时间戳与时间日期间相互转换
2017/12/11 Javascript
vue抽出组件并传值实例
2020/07/31 Javascript
python根据给定文件返回文件名和扩展名的方法
2015/03/27 Python
详解Python中的装饰器、闭包和functools的教程
2015/04/02 Python
Python浅拷贝与深拷贝用法实例
2015/05/09 Python
Python 操作文件的基本方法总结
2017/08/10 Python
Python2.7基于笛卡尔积算法实现N个数组的排列组合运算示例
2017/11/23 Python
python装饰器常见使用方法分析
2019/06/26 Python
Python Tensor FLow简单使用方法实例详解
2020/01/14 Python
Python使用os.listdir和os.walk获取文件路径
2020/05/21 Python
预订从美国飞往印度的机票:MyTicketsToIndia
2017/05/19 全球购物
药学专业大学生个人的自我评价
2013/11/04 职场文书
工程师岗位职责
2013/11/08 职场文书
工业设计专业个人求职信范文
2013/12/28 职场文书
公安局副政委班子个人对照检查材料
2014/10/04 职场文书
走群众路线剖析材料
2014/10/09 职场文书
幼儿园学前班幼儿评语
2014/12/29 职场文书
2015年高中班主任工作总结
2015/04/30 职场文书
Apache Calcite 实现方言转换的代码
2021/04/24 Servers
nginx之queue的具体使用
2022/06/28 Servers