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实现的登陆Discuz!论坛通用代码分享
Jul 11 Python
Python函数的周期性执行实现方法
Aug 13 Python
python logging日志模块的详解
Oct 29 Python
python中print()函数的“,”与java中System.out.print()函数中的“+”功能详解
Nov 24 Python
Python中getpass模块无回显输入源码解析
Jan 11 Python
Django模型修改及数据迁移实现解析
Aug 01 Python
python 中Arduino串口传输数据到电脑并保存至excel表格
Oct 14 Python
Python简易计算器制作方法代码详解
Oct 31 Python
python3-flask-3将信息写入日志的实操方法
Nov 12 Python
Django contrib auth authenticate函数源码解析
Nov 12 Python
python数据库批量插入数据的实现(executemany的使用)
Apr 30 Python
python游戏开发Pygame框架
Apr 22 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清除字符串中所有无用标签的方法
2014/12/01 PHP
WordPress伪静态规则设置代码实例
2020/12/10 PHP
JavaScript TO HTML 转换
2006/06/26 Javascript
通过JAVASCRIPT读取ASP设定的COOKIE
2007/02/15 Javascript
讲两件事:1.this指针的用法小探. 2.ie的attachEvent和firefox的addEventListener在事件处理上的区别
2007/04/12 Javascript
让AJAX不依赖后端接口实现方案
2012/12/03 Javascript
javaScript矢量图表库-gRaphael几行代码实现精美的条形图/饼图/点图/曲线图
2013/01/09 Javascript
jQuery自动切换/点击切换选项卡效果的小例子
2013/08/12 Javascript
Javascript自定义函数判断网站访问类型是PC还是移动终端
2014/01/10 Javascript
基于NodeJS的前后端分离的思考与实践(三)轻量级的接口配置建模框架
2014/09/26 NodeJs
JavaScript中textRange对象使用方法小结
2015/03/24 Javascript
每天一篇javascript学习小结(Date对象)
2015/11/13 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
2015/11/30 Javascript
vue双向绑定的简单实现
2016/12/22 Javascript
Angualrjs和bootstrap相结合实现数据表格table
2017/03/30 Javascript
web前端vue filter 过滤器
2018/01/12 Javascript
用ES6写全屏滚动插件的示例代码
2018/05/02 Javascript
vue 组件中添加样式不生效的解决方法
2018/07/06 Javascript
javascript/jquery实现点击触发事件的方法分析
2019/11/11 jQuery
Python实现的飞速中文网小说下载脚本
2015/04/23 Python
python实现搜索指定目录下文件及文件内搜索指定关键词的方法
2015/06/28 Python
在Python的Django框架中加载模版的方法
2015/07/16 Python
Python使用requests发送POST请求实例代码
2018/01/25 Python
Python进程间通信Queue实例解析
2018/01/25 Python
python 列表转为字典的两个小方法(小结)
2019/06/28 Python
解决os.path.isdir() 判断文件夹却返回false的问题
2019/11/29 Python
python实现企业微信定时发送文本消息的实例代码
2020/11/25 Python
Python 随机按键模拟2小时
2020/12/30 Python
python 批量将中文名转换为拼音
2021/02/07 Python
CSS3使用多列制作瀑布流
2016/05/10 HTML / CSS
html5 postMessage解决跨域、跨窗口消息传递方案
2016/12/20 HTML / CSS
1688平价精选商城:阿里集团旗下,工厂出厂价格直销
2017/04/24 全球购物
产品质量承诺书范文
2014/03/27 职场文书
食品质量与安全专业毕业生求职信
2014/08/11 职场文书
Vue实现下拉加载更多
2021/05/09 Vue.js
Python实现批量自动整理文件
2022/03/16 Python