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 相关文章推荐
Django中实现点击图片链接强制直接下载的方法
May 14 Python
Python中常用操作字符串的函数与方法总结
Feb 04 Python
Python优化技巧之利用ctypes提高执行速度
Sep 11 Python
Python文件与文件夹常见基本操作总结
Sep 19 Python
浅谈利用numpy对矩阵进行归一化处理的方法
Jul 11 Python
python 读写文件,按行修改文件的方法
Jul 12 Python
Python 忽略warning的输出方法
Oct 18 Python
对python的输出和输出格式详解
Dec 08 Python
Python Pandas 获取列匹配特定值的行的索引问题
Jul 01 Python
python字符串分割及字符串的一些常规方法
Jul 24 Python
django使用xadmin的全局配置详解
Nov 15 Python
Python自带的IDE在哪里
Jul 01 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 文件缓存函数
2011/10/08 PHP
php中使用base HTTP验证的方法
2015/04/20 PHP
PHP中异常处理的一些方法整理
2015/07/03 PHP
php实现在多维数组中查找特定value的方法
2015/07/29 PHP
十个PHP高级应用技巧果断收藏
2015/09/25 PHP
Zend Framework常用校验器详解
2016/12/09 PHP
通过JS自动隐藏手机浏览器的地址栏实现原理与代码
2013/01/02 Javascript
如何使用HTML5地理位置定位功能
2015/04/27 Javascript
Bootstrap CSS使用方法
2016/12/23 Javascript
jQuery插件JWPlayer视频播放器用法实例分析
2017/01/11 Javascript
npm国内镜像 安装失败的几种解决方案
2017/06/04 Javascript
微信小程序删除处理详解
2017/08/16 Javascript
浅谈ES6 模板字符串的具体使用方法
2017/11/07 Javascript
浅谈Vue.js路由管理器 Vue Router
2018/08/16 Javascript
说说如何在Vue.js中实现数字输入组件的方法
2019/01/08 Javascript
javascript设计模式 ? 单例模式原理与应用实例分析
2020/04/09 Javascript
JS加载解析Markdown文档过程详解
2020/05/19 Javascript
使用JavaScript通过前端发送电子邮件
2020/05/22 Javascript
[01:55]《走出家门看比赛》——DOTA2 2015国际邀请赛同城线下观战
2015/07/18 DOTA
利用python批量检查网站的可用性
2016/09/09 Python
tensorflow 用矩阵运算替换for循环 用tf.tile而不写for的方法
2018/07/27 Python
对Pyhon实现静态变量全局变量的方法详解
2019/01/11 Python
详解python持久化文件读写
2019/04/06 Python
python判断一个对象是否可迭代的例子
2019/07/22 Python
关于Django Models CharField 参数说明
2020/03/31 Python
Python绘图之柱形图绘制详解
2020/07/28 Python
Python函数__new__及__init__作用及区别解析
2020/08/31 Python
PyTorch中clone()、detach()及相关扩展详解
2020/12/09 Python
详解pandas中利用DataFrame对象的.loc[]、.iloc[]方法抽取数据
2020/12/13 Python
Speedo美国:澳大利亚顶尖泳衣制造商
2016/08/03 全球购物
最好的意大利皮夹克:D’Arienzo
2018/12/04 全球购物
乡镇信息公开实施方案
2014/03/23 职场文书
学生党员批评与自我批评
2014/10/15 职场文书
会计简历自我评价
2015/03/10 职场文书
大学运动会通讯稿
2015/07/18 职场文书
python用字节处理文件实例讲解
2021/04/13 Python