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 14 Python
python实现的DES加密算法和3DES加密算法实例
Jun 03 Python
总结python实现父类调用两种方法的不同
Jan 15 Python
Python创建对称矩阵的方法示例【基于numpy模块】
Oct 12 Python
mac下如何将python2.7改为python3
Jul 13 Python
解决Pandas的DataFrame输出截断和省略的问题
Feb 08 Python
Python语言检测模块langid和langdetect的使用实例
Feb 19 Python
Python中的异常处理try/except/finally/raise用法分析
Feb 28 Python
python写入数据到csv或xlsx文件的3种方法
Aug 23 Python
在 Python 中使用 7zip 备份文件的操作
Dec 11 Python
Python中的xlrd模块使用整理
Jun 15 Python
OpenCV绘制圆端矩形的示例代码
Aug 30 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
深入了解php4(1)--回到未来
2006/10/09 PHP
php miniBB中文乱码问题解决方法
2008/11/25 PHP
解析CodeIgniter自定义配置文件
2013/06/18 PHP
输入值/表单提交参数过滤有效防止sql注入的方法
2013/12/25 PHP
Laravel 5框架学习之Eloquent (laravel 的ORM)
2015/04/08 PHP
Laravel框架处理用户的请求操作详解
2019/12/20 PHP
PHP延迟静态绑定使用方法实例解析
2020/09/05 PHP
使用js操作cookie的一点小收获分享
2013/09/03 Javascript
js 赋值包含单引号双引号问题的解决方法
2014/02/26 Javascript
js函数名与form表单元素同名冲突的问题
2014/03/07 Javascript
javascript 兼容各个浏览器的事件
2015/02/04 Javascript
详解AngularJS中的表达式使用
2015/06/16 Javascript
javascript禁止访客复制网页内容的实现代码
2015/08/05 Javascript
js实现仿网易点击弹出提示同时背景变暗效果
2015/08/13 Javascript
noty ? jQuery通知插件全面解析
2016/05/18 Javascript
在node.js中怎么屏蔽掉favicon.ico的请求
2017/03/01 Javascript
three.js利用卷积法如何实现物体描边效果
2019/11/27 Javascript
你准备好迎接vue3.0了吗
2020/04/28 Javascript
[02:09]EHOME夺得首届辉夜杯冠军—现场颁奖仪式
2015/12/28 DOTA
Python写的PHPMyAdmin暴力破解工具代码
2014/08/06 Python
python中json格式数据输出的简单实现方法
2016/10/31 Python
Python实现 多进程导入CSV数据到 MySQL
2017/02/26 Python
Python实现的简单模板引擎功能示例
2017/09/02 Python
Python基于socket模块实现UDP通信功能示例
2018/04/10 Python
python获取天气接口给指定微信好友发天气预报
2020/12/28 Python
canvas里面如何基于随机点绘制一个多边形的方法
2018/06/13 HTML / CSS
StubHub美国:购买或出售您的门票
2019/07/09 全球购物
linux面试题参考答案(11)
2012/05/01 面试题
岗位职责的定义
2013/11/10 职场文书
环保公益广告语
2014/03/13 职场文书
幼儿园师德演讲稿
2014/05/06 职场文书
幼儿发展评估方案
2014/06/11 职场文书
大学生国家助学金感谢信
2015/01/23 职场文书
倡议书范文大全
2015/04/28 职场文书
2019年七夕情人节浪漫祝福语大全!
2019/08/08 职场文书
redis缓存存储Session原理机制
2021/11/20 Redis