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脚本实现下载合并SAE日志
Feb 10 Python
Python pickle模块用法实例分析
May 27 Python
python下载图片实现方法(超简单)
Jul 21 Python
python实现协同过滤推荐算法完整代码示例
Dec 15 Python
python通过Windows下远程控制Linux系统
Jun 20 Python
python 异或加密字符串的实例
Oct 14 Python
python实现诗歌游戏(类继承)
Feb 26 Python
Python除法之传统除法、Floor除法及真除法实例详解
May 23 Python
从pandas一个单元格的字符串中提取字符串方式
Dec 17 Python
python针对Oracle常见查询操作实例分析
Apr 30 Python
如何快速一次性卸载所有python包(第三方库)呢
Oct 20 Python
python实现简单的三子棋游戏
Apr 28 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
BBS(php & mysql)完整版(五)
2006/10/09 PHP
PHP代码判断设备是手机还是平板电脑(两种方法)
2015/10/19 PHP
php屏蔽错误及提示的方法
2020/05/10 PHP
setAttribute 与 class冲突解决
2008/02/17 Javascript
IE6下focus与blur错乱的解决方案
2011/07/31 Javascript
当自定义数据属性为json格式字符串时jQuery的data api问题探讨
2013/02/18 Javascript
文字溢出实现溢出的部分再放入一个新生成的div中具体代码
2013/05/17 Javascript
JS 通过系统时间限定动态添加 select option的实例代码
2016/06/09 Javascript
javascript另类方法实现htmlencode()与htmldecode()函数实例分析
2016/11/17 Javascript
文本溢出插件jquery.dotdotdot.js使用方法详解
2017/06/22 jQuery
jQuery代码优化方法总结
2018/01/29 jQuery
vue刷新和tab切换实例
2018/02/11 Javascript
如何为vuex实现带参数的 getter和state.commit
2019/01/04 Javascript
JavaScript两种计时器的实例讲解
2019/01/31 Javascript
JavaScript实现简单的弹窗效果
2020/05/19 Javascript
Vue如何基于vue-i18n实现多国语言兼容
2020/07/17 Javascript
[03:13]DOTA2-DPC中国联赛1月25日Recap集锦
2021/03/11 DOTA
Python脚本实现代码行数统计代码分享
2015/03/10 Python
Python爬虫设置代理IP(图文)
2018/12/23 Python
Python Pandas实现数据分组求平均值并填充nan的示例
2019/07/04 Python
Python数据结构dict常用操作代码实例
2020/03/12 Python
Python 实现微信自动回复的方法
2020/09/11 Python
pandas 按日期范围筛选数据的实现
2021/02/20 Python
使用css3实现的tab选项卡代码分享
2014/12/09 HTML / CSS
HTML5 解析规则分析
2009/08/14 HTML / CSS
野兽派官方旗舰店:THE BEAST 野兽派
2016/08/05 全球购物
乌克兰第一的珠宝网上商店:Gold.ua
2019/11/29 全球购物
Bloomingdale’s阿联酋:选购奢华时尚、美容及更多
2020/09/22 全球购物
C#里面可以避免一个类被其他类继承么?如何?
2013/09/26 面试题
大学应届毕业生个人求职信
2013/09/23 职场文书
小学生保护环境倡议书
2014/05/15 职场文书
教师党员批评与自我批评
2014/10/15 职场文书
MySQL之PXC集群搭建的方法步骤
2021/05/25 MySQL
vue Element-ui表格实现树形结构表格
2021/06/07 Vue.js
MySQL Innodb索引机制详细介绍
2021/11/23 MySQL
关于MybatisPlus配置双数据库驱动连接数据库问题
2022/01/22 Java/Android