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开发之for循环操作实例详解
Nov 12 Python
Pycharm学习教程(1) 定制外观
May 02 Python
pandas中去除指定字符的实例
May 18 Python
python自动发送测试报告邮件功能的实现
Jan 22 Python
Python计算时间间隔(精确到微妙)的代码实例
Feb 26 Python
python使用pygame模块实现坦克大战游戏
Mar 25 Python
Python发送手机动态验证码代码实例
Feb 28 Python
xadmin使用formfield_for_dbfield函数过滤下拉表单实例
Apr 07 Python
python使用nibabel和sitk读取保存nii.gz文件实例
Jul 01 Python
cookies应对python反爬虫知识点详解
Nov 25 Python
用Python编写简单的gRPC服务的详细过程
Jul 04 Python
详解Python中*args和**kwargs的使用
Apr 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
php中截取中文字符串的代码小结
2011/07/17 PHP
php传值赋值和传地址赋值用法实例分析
2015/06/20 PHP
PHP函数func_num_args用法实例分析
2015/12/07 PHP
php文件管理基本功能简单操作
2017/01/16 PHP
PHP7多线程搭建教程
2017/04/21 PHP
PHP+MySql实现一个简单的留言板
2020/07/19 PHP
学习YUI.Ext基础第一天
2007/03/10 Javascript
js正文内容高亮效果的实现方法
2013/06/30 Javascript
JQuery打造省市下拉框联动效果
2014/05/18 Javascript
JS和JQ的event对象区别分析
2014/11/24 Javascript
轻量级的原生js日历插件calendar.js使用指南
2015/04/28 Javascript
JQuery中层次选择器用法实例详解
2015/05/18 Javascript
JavaScript基本数据类型及值类型和引用类型
2015/08/25 Javascript
JavaScript中的函数(二)
2015/12/23 Javascript
Angularjs全局变量被作用域监听的正确姿势
2016/02/06 Javascript
Bootstrap媒体对象的实现
2016/05/01 Javascript
jQuery图片轮播插件——前端开发必看
2016/05/31 Javascript
javascript replace()第二个参数为函数时的参数用法
2016/12/26 Javascript
Jquery实时监听input value的实例
2017/01/26 Javascript
javacript replace 正则取字符串中的值并替换【推荐】
2018/09/13 Javascript
微信小程序:数据存储、传值、取值详解
2019/05/07 Javascript
[01:05:41]EG vs Optic Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
详解python里的命名规范
2018/07/16 Python
对python中的float除法和整除法的实例详解
2019/07/20 Python
python 并发编程 多路复用IO模型详解
2019/08/20 Python
python输入错误后删除的方法
2019/10/12 Python
美国面料纺织品商城:Fabric.com
2017/06/28 全球购物
机关门卫制度
2014/02/01 职场文书
致100米运动员广播稿
2014/02/14 职场文书
医学生临床实习自我评价
2014/03/07 职场文书
2014年营业员工作总结
2014/11/18 职场文书
学历证明样本
2015/06/16 职场文书
2016年精神文明建设先进个人事迹材料
2016/02/29 职场文书
承诺书怎么写 ?
2019/04/16 职场文书
小学五年级(说明文3篇)
2019/08/13 职场文书
Python爬虫之爬取最新更新的小说网站
2021/05/06 Python