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+matplotlib绘制旋转椭圆实例代码
Jan 12 Python
python打包压缩、读取指定目录下的指定类型文件
Apr 12 Python
Vue的el-scrollbar实现自定义滚动
May 29 Python
python查找指定文件夹下所有文件并按修改时间倒序排列的方法
Oct 21 Python
python实现各种插值法(数值分析)
Jul 30 Python
python多任务之协程的使用详解
Aug 26 Python
python实现截取屏幕保存文件,删除N天前截图的例子
Aug 27 Python
使用Python的networkx绘制精美网络图教程
Nov 21 Python
Python中SQLite如何使用
May 27 Python
Python网页解析器使用实例详解
May 30 Python
Django框架请求生命周期实现原理
Nov 13 Python
关于 Python json中load和loads区别
Nov 07 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
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
2010/06/11 PHP
查找mysql字段中固定字符串并替换的几个方法
2012/09/23 PHP
PHP文件缓存类实现代码
2015/10/26 PHP
Symfony查询方法实例小结
2017/06/28 PHP
PHP+AJAX 投票器功能
2017/11/11 PHP
用于table内容排序
2006/07/21 Javascript
javascript Window及document对象详细整理
2011/01/12 Javascript
Jquery 改变radio/checkbox选中状态,获取选中的值(示例代码)
2013/12/12 Javascript
推荐4个原生javascript常用的函数
2015/01/12 Javascript
JavaScript实现对下拉列表值进行排序的方法
2015/07/15 Javascript
avalon js实现仿微博拖动图片排序
2015/08/14 Javascript
JavaScript 七大技巧(一)
2015/12/13 Javascript
jQuery检测滚动条是否到达底部
2015/12/15 Javascript
jQuery实现的自定义滚动条实例详解
2016/09/20 Javascript
Actionscript与javascript交互实例程序(修改)
2016/09/22 Javascript
深入理解选择框脚本[推荐]
2016/12/13 Javascript
Bootstrap table两种分页示例
2016/12/23 Javascript
node.js使用免费的阿里云ip查询获取ip所在地【推荐】
2018/09/03 Javascript
layUI使用layer.open,在content打开数据表格,获取值并返回的方法
2019/09/26 Javascript
vue 使用 v-model 双向绑定父子组件的值遇见的问题及解决方案
2021/03/01 Vue.js
[00:47]TI7不朽珍藏III——沙王不朽展示
2017/07/15 DOTA
用pyqt5 给按钮设置图标和css样式的方法
2019/06/24 Python
python函数map()和partial()的知识点总结
2020/05/26 Python
Python必须了解的35个关键词
2020/07/16 Python
python 牛顿法实现逻辑回归(Logistic Regression)
2020/10/15 Python
css3实现超立体3D图片侧翻倾斜效果
2014/04/16 HTML / CSS
英国No.1文具和办公用品在线:Euroffice
2016/09/21 全球购物
公关活动策划方案
2014/05/25 职场文书
专题组织生活会方案
2014/06/15 职场文书
好好学习保证书
2015/02/26 职场文书
小学总务工作总结
2015/08/13 职场文书
大学生安全教育心得体会
2016/01/15 职场文书
化工生产实习心得体会
2016/01/22 职场文书
MySQL千万级数据表的优化实战记录
2021/08/04 MySQL
前端JS获取URL参数的4种方法总结
2022/04/05 Javascript
Sentry的安装、配置、使用教程(Sentry日志手机系统)
2022/07/23 Python