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服务器拒绝服务攻击代码
Jan 16 Python
在Windows8上的搭建Python和Django环境
Jul 03 Python
python进阶教程之动态类型详解
Aug 30 Python
Python实时获取cmd的输出
Dec 13 Python
Python中列表元素转为数字的方法分析
Jun 14 Python
教你学会使用Python正则表达式
Sep 07 Python
浅谈Django学习migrate和makemigrations的差别
Jan 18 Python
Python面向对象之继承和多态用法分析
Jun 08 Python
Python openpyxl 插入折线图实例
Apr 17 Python
解决tensorflow 释放图,删除变量问题
Jun 23 Python
如何快速理解python的垃圾回收机制
Sep 01 Python
python 如何用terminal输入参数
May 25 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
安装ImageMagick出现error while loading shared libraries的解决方法
2014/09/23 PHP
Yii2框架BootStrap样式的深入理解
2016/11/07 PHP
PHP多维数组元素操作类的方法
2016/11/14 PHP
php获取指定数量随机字符串的方法
2017/02/06 PHP
PHP实现腾讯与百度坐标转换
2017/08/05 PHP
JavaScript 布尔操作符解析  && || !
2012/08/10 Javascript
JavaScript实现简单图片翻转的方法
2015/04/17 Javascript
举例详解JavaScript中Promise的使用
2015/06/24 Javascript
使用JQuery FancyBox插件实现图片展示特效
2015/11/16 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
2015/11/30 Javascript
JavaScript生成带有缩进的表格代码
2016/06/15 Javascript
JS实现刷新父页面不弹出提示框的方法
2016/06/22 Javascript
jQuery联动日历的实例解析
2016/12/02 Javascript
原生js实现放大镜效果
2017/01/11 Javascript
JQuery查找子元素find()和遍历集合each的方法总结
2017/03/07 Javascript
基于 Vue 实现一个酷炫的 menu插件
2017/11/14 Javascript
解决vue 格式化银行卡(信用卡)每4位一个符号隔断的问题
2018/09/14 Javascript
Vue项目pdf(base64)转图片遇到的问题及解决方法
2018/10/19 Javascript
JS使用队列对数组排列,基数排序算法示例
2019/03/02 Javascript
vue基础之v-bind属性、class和style用法分析
2019/03/11 Javascript
Vue3.0结合bootstrap创建多页面应用
2019/05/28 Javascript
JavaScript原型继承和原型链原理详解
2020/02/04 Javascript
koa-passport实现本地验证的方法示例
2020/02/20 Javascript
[03:36]2014DOTA2 TI小组赛综述 八强诞生进军钥匙球馆
2014/07/15 DOTA
Python的组合模式与责任链模式编程示例
2016/02/02 Python
在Django中URL正则表达式匹配的方法
2018/12/20 Python
Python使用sklearn库实现的各种分类算法简单应用小结
2019/07/04 Python
Python Handler处理器和自定义Opener原理详解
2020/03/05 Python
什么是python的列表推导式
2020/05/26 Python
Vero Moda西班牙官方购物网站:丹麦BESTSELLER旗下知名女装品牌
2018/04/27 全球购物
ECHT官方网站:男女健身服
2020/02/14 全球购物
工商治理实习生的自我评价分享
2014/02/20 职场文书
2015仓库保管员年终工作总结
2015/05/13 职场文书
Mysql中 unique列插入重复值该怎么解决呢
2021/05/26 MySQL
常用的MongoDB查询语句的示例代码
2021/07/25 MongoDB
使用Python拟合函数曲线
2022/04/14 Python