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 Tkinter GUI编程入门介绍
Mar 10 Python
Python实现将一个大文件按段落分隔为多个小文件的简单操作方法
Apr 17 Python
python合并同类型excel表格的方法
Apr 01 Python
django 自定义过滤器(filter)处理较为复杂的变量方法
Aug 12 Python
Python将列表中的元素转化为数字并排序的示例
Dec 25 Python
Python实现FLV视频拼接功能
Jan 21 Python
Python数组并集交集补集代码实例
Feb 18 Python
Nginx+Uwsgi+Django 项目部署到服务器的思路详解
May 08 Python
pandas DataFrame运算的实现
Jun 14 Python
python中pow函数用法及功能说明
Dec 04 Python
pytorch 两个GPU同时训练的解决方案
Jun 01 Python
详解Python自动化之文件自动化处理
Jun 21 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,不用COM,生成excel文件
2006/10/09 PHP
php实现数组纵向转横向并过滤重复值的方法分析
2017/05/29 PHP
PHP大文件分割上传 PHP分片上传
2017/08/28 PHP
使用PHPExcel导出Excel表
2018/09/08 PHP
yii2.0框架数据库操作简单示例【添加,修改,删除,查询,打印等】
2020/04/13 PHP
php swoft框架实例用法
2020/12/22 PHP
jquery表单验证插件(jquery.validate.js)的3种使用方式
2015/03/28 Javascript
js实现选中复选框文字变色的方法
2015/08/14 Javascript
JS组件Bootstrap Table表格行拖拽效果实现代码
2020/08/27 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(二)
2016/09/14 Javascript
JQuery 获取多个select标签option的text内容(实例)
2017/09/07 jQuery
微信小程序自定义弹窗滚动与页面滚动冲突的解决方法
2019/07/16 Javascript
layui表单验证select下拉框实现验证的方法
2019/09/05 Javascript
Vue 3.0 全家桶抢先体验
2020/04/28 Javascript
JavaScript Tab菜单实现过程解析
2020/05/13 Javascript
原生js实现日期选择插件
2020/05/21 Javascript
JS实现多功能计算器
2020/10/28 Javascript
three.js中多线程的使用及性能测试详解
2021/01/07 Javascript
[58:25]VP vs RNG 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
Ubuntu 14.04+Django 1.7.1+Nginx+uwsgi部署教程
2014/11/18 Python
详解pandas安装若干异常及解决方案总结
2019/01/10 Python
Python将字符串常量转化为变量方法总结
2019/03/17 Python
python小白学习包管理器pip安装
2020/06/09 Python
python中re模块知识点总结
2021/01/17 Python
Python plt 利用subplot 实现在一张画布同时画多张图
2021/02/26 Python
深入浅析css3 中display box使用方法
2015/11/25 HTML / CSS
html5桌面通知(Web Notifications)实例解析
2014/07/07 HTML / CSS
美国在线家装零售商:Build.com
2016/09/02 全球购物
写给妈妈的道歉信
2014/01/11 职场文书
小学师德标兵先进事迹材料
2014/05/25 职场文书
授权委托书(法人单位用)
2014/09/29 职场文书
行政前台岗位职责
2015/04/16 职场文书
辩护词范文大全
2015/05/21 职场文书
大学生社区义工服务心得体会
2016/01/22 职场文书
Pytorch反向传播中的细节-计算梯度时的默认累加操作
2021/06/05 Python
python blinker 信号库
2022/05/04 Python