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中映射类型(字典)操作符的概念和使用
Aug 19 Python
python中input()与raw_input()的区别分析
Feb 27 Python
Python中elasticsearch插入和更新数据的实现方法
Apr 01 Python
Python设计模式之观察者模式原理与用法详解
Jan 16 Python
Python子类继承父类构造函数详解
Feb 19 Python
Python3远程监控程序的实现方法
Jul 15 Python
Django Rest framework三种分页方式详解
Jul 26 Python
python3.8与pyinstaller冲突问题的快速解决方法
Jan 16 Python
python实现翻译word表格小程序
Feb 27 Python
Python脚本破解压缩文件口令实例教程(zipfile)
Jun 14 Python
Python利用matplotlib绘制散点图的新手教程
Nov 05 Python
Python使用openpyxl模块处理Excel文件
Jun 05 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
Re:从零开始的异世界生活 第2季 开播啦
2020/07/24 日漫
php 仿Comsenz安装效果代码打包提供下载
2010/05/09 PHP
php面向对象中static静态属性和静态方法的调用
2015/02/08 PHP
浅谈laravel 5.6 安装 windows上使用composer的安装过程
2019/10/18 PHP
Jquery乱码的一次解决过程 图解教程
2010/02/20 Javascript
在网站上应该用的30个jQuery插件整理
2011/11/03 Javascript
jQuery EasyUI API 中文文档 - Tree树使用介绍
2011/11/19 Javascript
jquery实现弹出窗口效果的实例代码
2013/11/28 Javascript
js统计录入文本框中字符的个数并加以限制不超过多少
2014/05/23 Javascript
JS中产生20位随机数以0-9为例也可以是a-z A-Z
2014/08/01 Javascript
WEB前端设计师常用工具集锦
2014/12/09 Javascript
异步JS框架的作用以及实现方法
2015/10/29 Javascript
微信小程序 Image API实例详解
2016/09/30 Javascript
微信JSAPI Ticket接口签名详解
2020/06/28 Javascript
详解如何让Express支持async/await
2017/10/09 Javascript
微信小程序如何获取用户信息
2018/01/26 Javascript
[30:51]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#1Liquid VS MVP.Phx第一局
2016/03/04 DOTA
研究Python的ORM框架中的SQLAlchemy库的映射关系
2015/04/25 Python
在Python中操作日期和时间之gmtime()方法的使用
2015/05/22 Python
Python中矩阵库Numpy基本操作详解
2017/11/21 Python
python 打印直角三角形,等边三角形,菱形,正方形的代码
2017/11/21 Python
Python的CGIHTTPServer交互实现详解
2018/02/08 Python
Python使用sorted对字典的key或value排序
2018/11/15 Python
Django 日志配置按日期滚动的方法
2019/01/31 Python
python脚本执行CMD命令并返回结果的例子
2019/08/14 Python
ProBikeKit美国官网:自行车套件,跑步和铁人三项套件
2016/10/13 全球购物
党员承诺书怎么写
2014/05/20 职场文书
酒店管理求职信
2014/06/09 职场文书
2014年教师节演讲稿
2014/09/03 职场文书
2014年重阳节敬老活动方案
2014/09/16 职场文书
化工见习报告范文
2014/10/31 职场文书
社团个人总结范文
2015/03/05 职场文书
酒店人事主管岗位职责
2015/04/11 职场文书
单位工作证明范本
2015/06/15 职场文书
Go 在 MongoDB 中常用查询与修改的操作
2021/05/07 Golang
基于HTML十秒做出淘宝页面
2021/10/24 HTML / CSS