Node.JS中UDP打洞穿透内网路由,架设内网服务器技术详解及源码


发布者 ourjs  发布时间 1514948350188
关键字 JS学习  JavaScript 
在制作一款私有云网络存储产品时,很多客户反应,他们希望能远程访问。远程访问内网服务器成本最低的方式应该就是P2P内网穿透了,这里介绍一下实现原理。

UDP穿透原理


打洞主要采用的是udp的无面向连接的特性来实现,同过user1连接server,打通user1的对外ip和端口,然后在一段时间内server都能通过这个端口和IP实现路由穿透,向局域网内的服务器发送消息。

此时user2连接server,打通uer2对外的ip和端口,然后user1和user2通过彼此已经打通的对外ip和端口实现通讯。

这就是P2P不同网络间通信协议的基础。

为了简单起见,这只仅演示从 user1 向 server 打洞穿透的过程。需要先准备一台服务器和一台本地电脑。

UDP打洞源代码


因为UDP是既可以侦听又可以发送数据的,所以node.js的代码实现非常简单,服务器和本地用一套代码即可。命名为 onceair.udp.server.js 此文件接收命令行参数,侦听本地 8090 端口:

var os        = require('os')
var fs        = require('fs')
var net       = require('net')
var dgram     = require('dgram')
var cp        = require('child_process')
var path      = require('path')
var udp       = dgram.createSocket('udp4')
udp.on('message', function(data, ipdr) {
  console.log('message')
  console.log(data.toString())
  console.log(ipdr)
})
udp.on('error', function(err) {
  console.log('error')
  console.log(arguments)
})
udp.on('listening', function(err) {
  console.log('listening')
  console.log(arguments)
})
udp.bind(8090)
console.log('udp listening on port 8090')


var send = function(message, port, host) {
  console.log('send')
  console.log(arguments)
  udp.send(Buffer.from(message), port || 8090, host || 'anynb.com')
}

//called directly in command line
if (require.main === module) {
  var port = parseInt(process.argv[2])
  var host = process.argv[3]
  if (port) {
    send('echo', port, host)
  } else {
    send('echo')
  }
}


示例


将 udp.server 上传到服务器端,然后运行在后台运行,默认侦听 8090 端口

/root/node/bin/node onceair.udp.server.js

在客户端向服务器的 8090 发送消息,同时本地侦听 8090

$ node onceair.udp.server.js 8090 112.124.126.185

服务器端接收到响应,我们看到这里接收到的客户端公网IP是180.173.98.126,端口号是 43191,这是路由转出消息的随机端口,通过这个端口,就能连接到本地UDP侦听的8090端口,即是一个临时的session通道。

message
echo
{ address: '180.173.98.126',
  family: 'IPv4',
  port: 43191,
  size: 4 }

Ctrl + C 中上 onceair.udp.server.js 进程,然后向这个IP和穿透的端口发送数据包,记住操作时间不要太长,否则打通的 session 可能会过期。

/root/node/bin/node onceair.udp.server.js 43191 180.173.98.126

udp listening on port 8090
send
{ '0': 'echo', '1': 43191, '2': '180.173.98.126' }
listening
{}

本地接收到的消息,代表通过已经打通

message
echo
{ address: '112.124.126.185',
  family: 'IPv4',
  port: 8090,
  size: 4 }



TCP的内网穿透


实现基于TCP协议的p2p“打洞”过程中,最主要的问题不是来自于TCP协议,而是来自于来自于应用 程序的API接口。这是由于标准的伯克利(Berkeley)套接字的API是围绕着构建客户端/服务器程序 而设计的,API允许TCP流套接字通过调用connect()函数来建立向外的连接,或者通过listen()和 accept函数接受来自外部的连接,但是,API不提供类似UDP那样的,同一个端口既可以向外连接, 又能够接受来自外部的连接。而且更糟的是,TCP的套接字通常仅允许建立1对1的响应,即应用程 序在将一个套接字绑定到本地的一个端口以后,任何试图将第二个套接字绑定到该端口的操作都会 失败。

因此要实现基于TCP的内网穿透,在内网架设一台HTTP网站,要比UDP复杂得多。




回复 (6)
  • #
  • #1 傅丹儿 1520597471398

    加粗文本

  • #2 朱许小 1555378266783

    组播可用内网穿透吗

  • #3 钱天匹 1555419994682
  • #4 雷礼争 1559719657937

    node onceair.udp.server.js 8090 112.124.126.185 后面的ip是客户端ip吗?

  • #5 雷礼争 1559720137802

    This is Privoxy 3.0.26 on PC-20181104GAPK (127.0.0.1), port 25378 No server or forwarder data received Your request for http://78.141.203.6/ could not be fulfilled, because the connection to 78.141.203.6 (127.0.0.1) has been closed before Privoxy received any data for this request.

    This is often a temporary failure, so you might just try again.

    If you get this message very often, consider disabling connection-sharing (which should be off by default). If that doesn't help, you may have to additionally disable support for connection keep-alive by setting keep-alive-timeout to 0.

    More Privoxy: Privoxy main page Shut down - Do not deploy this build in a production environment, this is a one click Denial Of Service attack!!! View the current configuration View the source code version numbers View or toggle the tags that can be set based on the clients address View the request headers Look up which actions apply to a URL and why View the proxy-auto-config(PAC) script. Documentation Support and Service: The Privoxy Team values your feedback.

    Please have a look at the User Manual to learn how to get support or report problems.

    If you want to support the Privoxy Team, you can participate or donate.

  • #6 雷礼争 1559720168412

    没有任何用

微信扫码 立即评论




 热门文章 - 分享最多
  1. redis、memcache和mongodb各自的优缺点是什么,怎么选择呢?
  2. 垄断"开源硬件"树莓派芯片的供应商博通要收购高通了
  3. Node.JS 8.x和9.x新特性:N-API,NPM5,ERROR CODE
  4. 比特币最近为何会暴跌?大资金如何靠做空比特币获利
  5. 红衣教主周鸿祎会不会成为中国首富
  6. 移动端开发框架哪个好?jQuery/Vue/AngularJS有哪些区别和优缺点?
  7. NodeJS动态传参特性:不定个数参数的省略,默认值与解构
  8. 40行JavaScript代码实现的3D旋转魔方动画效果
  9. Node.JS与USB接口通信:检测U盘/移动硬盘插拔事件和发送接数据
  10. OnceAir顽石企业私有云网盘使用介绍

 相关阅读
  1. 移动端开发框架哪个好?jQuery/Vue/AngularJS有哪些区别和优缺点?
  2. Node.JS 8.x和9.x新特性:N-API,NPM5,ERROR CODE
  3. Node.JS读取中文TXT编码文件显示乱码问题解决方案
  4. Node.JS与USB接口通信:检测U盘/移动硬盘插拔事件和发送接数据
  5. NodeJS动态传参特性:不定个数参数的省略,默认值与解构
  6. 从 Node 到 Go:一个粗略的比较—GO平均性能比JavaScript快十几倍
  7. Node.JS中如何快速扫描端口并发现局域网内的Web服务器地址(80)
  8. Node.JS循环递归复制文件夹目录及其子文件夹下的所有文件
  9. 正则中test、exec、match的简单区别,以及括号的用法
  10. node.js使用unzip解压zip包指定文件,提取 word/excel (docx/pptx/xlsx) 文本内容

  开源的 OurJS
OurJS开源博客已经迁移到 OnceOA 平台。

  关注我们
扫一扫即可关注我们:
OnceJS

OnceOA