Python实现TCP协议下的端口映射功能的脚本程序示例


Posted in Python onJune 14, 2016

1 端口映射

举个例子来说明一下端口映射的作用。

有A、B、C三台计算机,A、B互通,B、C互通,但是A、C不通,这个时候在C上开了一个Web服务,如何让A访问C的Web服务?

最简单有效的办法就是在B上开一个端口映射服务,然后让A访问B的某个端口,B将这个端口上的所有流量全部转发到C的Web服务端口上,同时将C上Web服务返回的流量也全部转发给A。这样对A来说,以B为跳板,实现了间接访问C上Web服务的目的。

2 实现流程

端口映射的原理并不复杂,本文以TCP为例介绍一下实现过程,简单画了个时序图(如下),这里就不再用文字赘述了。

Python实现TCP协议下的端口映射功能的脚本程序示例

需要注意的是,由于端口映射只是单纯的流量转发,对应用层数据不进行处理,所以对于多通道协议是无法支持的(如FTP协议)。

3 代码示例

按照上面的流程,Python实现如下(建议从后向前看):

# -*- coding: utf-8 -*-
# tcp mapping created by hutaow(hutaow.com) at 2014-08-31

import socket
import threading

# 端口映射配置信息
CFG_REMOTE_IP = '192.168.0.10'
CFG_REMOTE_PORT = 22
CFG_LOCAL_IP = '0.0.0.0'
CFG_LOCAL_PORT = 10022

# 接收数据缓存大小
PKT_BUFF_SIZE = 2048

# 调试日志封装
def send_log(content):
  print content
  return

# 单向流数据传递
def tcp_mapping_worker(conn_receiver, conn_sender):
  while True:
    try:
      data = conn_receiver.recv(PKT_BUFF_SIZE)
    except Exception:
      send_log('Event: Connection closed.')
      break

    if not data:
      send_log('Info: No more data is received.')
      break

    try:
      conn_sender.sendall(data)
    except Exception:
      send_log('Error: Failed sending data.')
      break

    # send_log('Info: Mapping data > %s ' % repr(data))
    send_log('Info: Mapping > %s -> %s > %d bytes.' % (conn_receiver.getpeername(), conn_sender.getpeername(), len(data)))

  conn_receiver.close()
  conn_sender.close()

  return

# 端口映射请求处理
def tcp_mapping_request(local_conn, remote_ip, remote_port):
  remote_conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  try:
    remote_conn.connect((remote_ip, remote_port))
  except Exception:
    local_conn.close()
    send_log('Error: Unable to connect to the remote server.')
    return

  threading.Thread(target=tcp_mapping_worker, args=(local_conn, remote_conn)).start()
  threading.Thread(target=tcp_mapping_worker, args=(remote_conn, local_conn)).start()

  return

# 端口映射函数
def tcp_mapping(remote_ip, remote_port, local_ip, local_port):
  local_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  local_server.bind((local_ip, local_port))
  local_server.listen(5)

  send_log('Event: Starting mapping service on ' + local_ip + ':' + str(local_port) + ' ...')

  while True:
    try:
      (local_conn, local_addr) = local_server.accept()
    except KeyboardInterrupt, Exception:
      local_server.close()
      send_log('Event: Stop mapping service.')
      break

    threading.Thread(target=tcp_mapping_request, args=(local_conn, remote_ip, remote_port)).start()

    send_log('Event: Receive mapping request from %s:%d.' % local_addr)

  return

# 主函数
if __name__ == '__main__':
  tcp_mapping(CFG_REMOTE_IP, CFG_REMOTE_PORT, CFG_LOCAL_IP, CFG_LOCAL_PORT)

4 运行

运行效果如下,192.168.0.20通过连接映射服务器的10022端口,成功访问192.168.0.10的SSH服务(22端口):

Python实现TCP协议下的端口映射功能的脚本程序示例

Python 相关文章推荐
Python 过滤字符串的技巧,map与itertools.imap
Sep 06 Python
python网络编程学习笔记(一)
Jun 09 Python
Python下singleton模式的实现方法
Jul 16 Python
深入理解python多进程编程
Jun 12 Python
CentOS6.5设置Django开发环境
Oct 13 Python
python WindowsError的错误代码详解
Jul 23 Python
对python中的try、except、finally 执行顺序详解
Feb 18 Python
python threading和multiprocessing模块基本用法实例分析
Jul 25 Python
Python使用指定字符长度切分数据示例
Dec 05 Python
基于Python和PyYAML读取yaml配置文件数据
Jan 13 Python
浅谈TensorFlow之稀疏张量表示
Jun 30 Python
解决Python字典查找报Keyerror的问题
May 26 Python
浅谈python新手中常见的疑惑及解答
Jun 14 #Python
Python中死锁的形成示例及死锁情况的防止
Jun 14 #Python
实例探究Python以并发方式编写高性能端口扫描器的方法
Jun 14 #Python
Python使用dis模块把Python反编译为字节码的用法详解
Jun 14 #Python
Python的Flask框架中使用Flask-Migrate扩展迁移数据库的教程
Jun 14 #Python
Python的Flask框架中使用Flask-SQLAlchemy管理数据库的教程
Jun 14 #Python
全面了解Python的getattr(),setattr(),delattr(),hasattr()
Jun 14 #Python
You might like
PHP Memcached应用实现代码
2010/02/08 PHP
php引用地址改变变量值的问题
2012/03/23 PHP
php权重计算方法代码分享
2014/01/09 PHP
30个php操作redis常用方法代码例子
2014/07/05 PHP
php按单词截取字符串的方法
2015/04/07 PHP
PHP扩展安装方法步骤解析
2020/11/24 PHP
jQuery插件 tabBox实现代码
2010/02/09 Javascript
javascript 表格内容排序 简单操作示例代码
2014/01/03 Javascript
一些老手都不一定知道的JavaScript技巧
2014/05/06 Javascript
javascript将url中的参数加密解密代码
2014/11/17 Javascript
jQuery中[attribute]选择器用法实例
2014/12/31 Javascript
jQuery中:password选择器用法实例
2015/01/03 Javascript
jQuery获取radio选中项的值实例
2016/06/18 Javascript
js中数组的常用方法小结
2016/12/30 Javascript
微信小程序中用WebStorm使用LESS
2017/03/08 Javascript
给Easyui-Datebox设置隐藏或者不可用的解决方法
2017/05/26 Javascript
JavaScript实现HTML5游戏断线自动重连的方法
2017/09/18 Javascript
webpack 4.0.0-beta.0版本新特性介绍
2018/02/10 Javascript
jQuery UI实现动画效果代码分享
2018/08/19 jQuery
原生JS检测CSS3动画是否结束的方法详解
2019/01/27 Javascript
js实现移动端tab切换时下划线滑动效果
2019/09/08 Javascript
jQuery实现form表单基于ajax无刷新提交方法实例代码
2019/11/04 jQuery
Javascript前端下载后台传来的文件流代码实例
2020/08/18 Javascript
王纯业的Python学习笔记 下载
2007/02/10 Python
python 打印出所有的对象/模块的属性(实例代码)
2016/09/11 Python
Python中列表list以及list与数组array的相互转换实现方法
2017/09/22 Python
opencv python 2D直方图的示例代码
2018/07/20 Python
centos6.5安装python3.7.1之后无法使用pip的解决方案
2019/02/14 Python
Zalando Lounge瑞士:时尚与生活方式购物俱乐部
2020/03/12 全球购物
自我评价范文点评
2013/12/04 职场文书
幼儿园消防演练方案
2014/02/13 职场文书
服装仓管员岗位职责
2014/06/17 职场文书
校园元旦活动总结
2014/07/09 职场文书
门面房租房协议书
2014/12/01 职场文书
详解JS WebSocket断开原因和心跳机制
2021/05/07 Javascript
Python安装使用Scrapy框架
2022/04/12 Python