继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

二百行代码做一个内网穿透,代码+讲解

王牌
关注TA
已关注
手记 6
粉丝 21
获赞 207

本文关键词:内网穿透

内网穿透是用来做什么的,大家都知道本地的电脑做的网站外网是访问不了的,只能通过127.0.0.1在本地访问。但是在本地的程序想调试微信的程序,或者想让别人在远程能访问到你电脑的程序。内网穿透就派上用上了。

用法:

1、在有独立ip的一台服务器上运行node server.js。

2、在本地运行 node client.js

3、世界上任何一个地点访问:http://独立ip:7777就可以访问到本地电脑里的127.0.0.1:80

说明:端口在client跟server代码的最后一行都可以换。

下面是client.js的代码

(function() {
  var Net;

  Net = require('net');


  Client = (function() {
    function _Class(localAddress, remoteAddress) {
      this.localAddress = localAddress;
      this.remoteAddress = remoteAddress;
      this.createDaemonSocket();
    }

    _Class.prototype.createDaemonSocket = function() {
      var ping;
      ping = Buffer.from([0]);
      this.daemonSocket = this.connectRemote((function(_this) {
        return function() {
          _this.daemonSocket.ref();
          _this.daemonSocket.on('data', function(data) {
            var uuid;
            if (data.length === 4) {
              uuid = data.readInt32LE(0);
              console.info("request pipe " + uuid);
              return _this.createTunnel(uuid);
            }
          });
          _this.daemonSocket.write(ping);
          return setInterval(function() {
            return _this.daemonSocket.write(ping);
          }, 10000);
        };
      })(this));
      return this.daemonSocket.on('close', (function(_this) {
        return function() {
          return setTimeout(function() {
            return _this.createDaemonSocket();
          }, 1000);
        };
      })(this));
    };

    _Class.prototype.connectRemote = function(cb) {
      var socket;
      socket = Net.connect(this.remoteAddress.port, this.remoteAddress.ip, cb);
      socket.on('error', console.error);
      return socket;
    };

    _Class.prototype.connectLocal = function(cb) {
      var socket;
      socket = Net.connect(this.localAddress.port, this.localAddress.ip, cb);
      socket.on('error', console.error);
      return socket;
    };

    _Class.prototype.createTunnel = function(uuid) {
      var ping, socket;
      ping = new Buffer(4);
      ping.writeInt32LE(uuid, 0);
      return socket = this.connectRemote((function(_this) {
        return function() {
          var local;
          console.info("connect remote " + uuid);
          return local = _this.connectLocal(function() {
            console.info("connect local " + uuid);
            socket.write(ping);
            socket.pipe(local).pipe(socket);
            return console.info("piped " + uuid);
          });
        };
      })(this));
    };

    return _Class;

  })();

}).call(this);

new Client({'port':80,'ip':'127.0.0.1'},{'port':8888,'ip':'127.0.0.1'});

下面是server.js的代码

(function() {
  var Net;

  Net = require('net');


  Client = (function() {
    function _Class(localAddress, remoteAddress) {
      this.localAddress = localAddress;
      this.remoteAddress = remoteAddress;
      this.createDaemonSocket();
    }

    _Class.prototype.createDaemonSocket = function() {
      var ping;
      ping = Buffer.from([0]);
      this.daemonSocket = this.connectRemote((function(_this) {
        return function() {
          _this.daemonSocket.ref();
          _this.daemonSocket.on('data', function(data) {
            var uuid;
            if (data.length === 4) {
              uuid = data.readInt32LE(0);
              console.info("request pipe " + uuid);
              return _this.createTunnel(uuid);
            }
          });
          _this.daemonSocket.write(ping);
          return setInterval(function() {
            return _this.daemonSocket.write(ping);
          }, 10000);
        };
      })(this));
      return this.daemonSocket.on('close', (function(_this) {
        return function() {
          return setTimeout(function() {
            return _this.createDaemonSocket();
          }, 1000);
        };
      })(this));
    };

    _Class.prototype.connectRemote = function(cb) {
      var socket;
      socket = Net.connect(this.remoteAddress.port, this.remoteAddress.ip, cb);
      socket.on('error', console.error);
      return socket;
    };

    _Class.prototype.connectLocal = function(cb) {
      var socket;
      socket = Net.connect(this.localAddress.port, this.localAddress.ip, cb);
      socket.on('error', console.error);
      return socket;
    };
内网穿透– 用我最直白的语言解读优秀源码
    _Class.prototype.createTunnel = function(uuid) {
      var ping, socket;
      ping = new Buffer(4);
      ping.writeInt32LE(uuid, 0);
      return socket = this.connectRemote((function(_this) {
        return function() {
          var local;
          console.info("connect remote " + uuid);
          return local = _this.connectLocal(function() {
            console.info("connect local " + uuid);
            socket.write(ping);
            socket.pipe(local).pipe(socket);
            return console.info("piped " + uuid);
          });
        };
      })(this));
    };

    return _Class;

  })();

}).call(this);

new Client({'port':80,'ip':'127.0.0.1'},{'port':8888,'ip':'127.0.0.1'});

大体的流程是:
1、server.js启动,监听8888跟7777端口。
2、client.js启动,与server的8888端口链接,这个TCP链接是主要链接,后面的其他TCP分裂,client与server协商都靠这个TCP,此链接不参与具体业务数据传送。
3、server上面的7777有TCP链接接入,server给此socket起一个唯一数,并作为对象的键存起来,而且通过主TCP通道高速client。
4、client收到后,与server新建一个TCP链接,第一个信息就是这个唯一数,server把此socket与7777端口进来的socket对接,转发数据。
5、至此,一个单线程、事件驱动、多tcp的内网穿透开启完毕

内网穿透– 用我最直白的语言解读优秀源码

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP