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 可爱的大小写
Sep 06 Python
Python编程对列表中字典元素进行排序的方法详解
May 26 Python
wxpython实现图书管理系统
Mar 12 Python
Python基础教程之利用期物处理并发
Mar 29 Python
基于Django与ajax之间的json传输方法
May 29 Python
基于wxPython的GUI实现输入对话框(2)
Feb 27 Python
Python实现的栈、队列、文件目录遍历操作示例
May 06 Python
Python应用领域和就业形势分析总结
May 14 Python
python之pymysql模块简单应用示例代码
Dec 16 Python
Python命令行click参数用法解析
Dec 19 Python
python3让print输出不换行的方法
Aug 24 Python
Python爬虫入门案例之爬取二手房源数据
Oct 16 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 面向对象 final类与final方法
2010/05/05 PHP
PHP页面间参数传递的四种方法详解
2013/06/09 PHP
php实现四舍五入的方法小结
2015/03/03 PHP
PHP可变函数学习小结
2015/11/29 PHP
分享PHP源码批量抓取远程网页图片并保存到本地的实现方法
2015/12/01 PHP
PHP中单例模式的使用场景与使用方法讲解
2019/03/18 PHP
JavaScript中Array 对象相关的几个方法
2006/12/22 Javascript
用javascript实现兼容IE7的类库 IE7_0_9.zip提供下载
2007/08/08 Javascript
javascript网页关键字高亮代码
2008/07/30 Javascript
JavaScript实现将文本框的值插入指定位置的方法
2015/08/13 Javascript
AngularJS 日期格式化详解
2015/12/23 Javascript
Vue 父子组件、组件间通信
2017/03/08 Javascript
详解angular中的作用域及继承
2017/05/31 Javascript
微信小程序自定义导航隐藏和显示功能
2017/06/13 Javascript
详解Vue 事件修饰符capture 的使用
2017/12/29 Javascript
vue引入js数字小键盘的实现代码
2018/05/14 Javascript
微信小程序利用canvas 绘制幸运大转盘功能
2018/07/06 Javascript
如何通过shell脚本自动生成vue文件详解
2019/09/10 Javascript
使用JavaScript实现贪吃蛇游戏
2020/09/29 Javascript
windows下python连接oracle数据库
2017/06/07 Python
安装Pycharm2019以及配置anconda教程的方法步骤
2019/11/11 Python
基于Python批量生成指定尺寸缩略图代码实例
2019/11/20 Python
numpy中三维数组中加入元素后的位置详解
2019/11/28 Python
python3实现绘制二维点图
2019/12/04 Python
Python字典生成式、集合生成式、生成器用法实例分析
2020/01/07 Python
python如何基于redis实现ip代理池
2020/01/17 Python
python代码实现猜拳小游戏
2020/11/30 Python
python爬取抖音视频的实例分析
2021/01/19 Python
协议书模板
2014/04/23 职场文书
法人授权委托书范本
2014/09/17 职场文书
大学生助学金感谢信
2015/01/21 职场文书
2015感人爱情寄语
2015/02/26 职场文书
村官个人总结范文
2015/03/03 职场文书
通知书大全
2015/04/27 职场文书
MySQL锁机制
2021/04/05 MySQL
Nginx的gzip相关介绍
2022/05/11 Servers