【问题标题】:Listen multiple tcp ports with nodejs使用 nodejs 监听多个 tcp 端口
【发布时间】:2020-08-31 18:41:03
【问题描述】:

.--------。 .---------。 .---------。 |客户 | ---> |服务器 A | |控制器 | '--------' '---------' '---------' .--------。 .---------。 .---------。 |客户 | |服务器 A | |控制器 | '--------' '---------' '---------' .--------。 .---------。 |客户 | ---------------------> |控制器 | '--------' '---------' .--------。 .---------。 |客户 |

我想使用nodejs同时监听两个TCP端口。一个用于客户端,另一个是控制器。首先,客户端向服务器发送认证请求。然后,服务器将带有随机数的客户端地址广播到特定端口。客户端获得随机数后,将其与自己的签名和自己的公钥一起发送给控制器。然后,控制器通过验证即将到来的公钥和随机数来检查来自客户端的数据。

但是,我必须监听两个不同的端口,而我无法在 nodejs 上使用 TCP。我怎样才能做到这一点?谢谢。

这是我的代码,

服务器部分:

const fs = require("fs");

// Get the filenames of user1 directory
dir_name = "../wallet/user1/";
const user1_info_dir = fs.readdirSync(dir_name);             

// Assign specific file names on them
const user1_pub_file = dir_name + user1_info_dir[1];

// Read .pem by using "pem-file" package
const user1_pub_pem = fs.readFileSync(user1_pub_file)


const net = require('net'); 
const host = "127.0.0.1";
const port = 9000;


const server = net.createServer(); 


server.listen(port, host, () => { 
    console.log(`TCP Client listening on ${host}:${port}`); 
}); 


let sockets = []; 
server.on('connection', (socket) => { 
    var clientAddress = `${socket.remoteAddress}:${socket.remotePort}`; 
    console.log(`new client connected: ${clientAddress}`); 
    
    sockets.push(socket); 
    // console.log(sockets);
   
    socket.once('data', (data) => {
        console.log(`Client ${clientAddress}: ${data}`); 
        const crypto = require('crypto');
        const buf = crypto.randomBytes(256);
        //console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`);   
                
        //Write the data back to all the connected, the client will receive it as data from the server 
        sockets.forEach((sock) => { 
            var arr = [user1_pub_pem, buf];
            sock.write(Buffer.concat(arr));            
        }); 
    });

    // Add a 'close' event handler to this instance of socket 
    socket.on('close', (data) => { 
        let index = sockets.findIndex((o) => { 
            return o.remoteAddress === socket.remoteAddress && o.remotePort === socket.remotePort; 
        })

        if (index !== -1) sockets.splice(index, 1); 

        sockets.forEach((sock) => { 
            sock.write(`${clientAddress} disconnected\n`); 
        });

        console.log(`connection closed: ${clientAddress}`); 
    });

    // Add a 'error' event handler to this instance of socket 
    socket.on('error', (err) => { 
        console.log(`Error occurred in ${clientAddress}: ${err.message}`); 
    });
}); 

客户端部分:

var readlineSync = require("readline-sync");
var net = require("net");
var host = "127.0.0.1";
var port = 9000;

const fs = require("fs");
const crypto = require('crypto');

dir_name = "../wallet/user1/";
const user1_info_dir = fs.readdirSync(dir_name);             // Get the filenames of user1 directory

const user1_priv_file = dir_name + user1_info_dir[0];        // Assign specific file names on them
const user1_pub_file = dir_name + user1_info_dir[1];
const user1_sig_file = dir_name + user1_info_dir[2];

const user1_priv_pem = fs.readFileSync(user1_priv_file)      // Read .pem by using "pem-file" package
const user1_pub_pem = fs.readFileSync(user1_pub_file)
const user1_sig_pem = fs.readFileSync(user1_sig_file)


var client = null;

function openConnection () { 
    if(client) {
        console.log("Connection is already open --");
        setTimeout(function (){
            menu();
        }, 0);
        return;
    }

    client = new net.Socket();
    
    client.on("error", function(err) {
        client.destroy();
        client = null;
        console.log("ERROR: Connection could not be opened. Msg : %s", err.message);
        setTimeout(function (){
            menu();
        }, 0); 
    });

    client.connect(port, host, function () {
        console.log("Connection opened succesfully");
        client.write("Hello my darling !");
   });

    client.on("data", function (data_from_sv) {
        console.log("Recieved: %s", data_from_sv);
        my_ip = client.address().address;
        var my_ip_buf = Buffer.from(my_ip, 'utf8');
        var durT = new Date();
        durT.setTime(1332403882588);        
        durT_str = durT.toString();
        duration_time = Buffer.from(durT_str, 'utf8');
        my_pub_key = user1_pub_pem;
        my_prv_key = user1_priv_pem;
        var arr = [data_from_sv, my_ip_buf, duration_time, my_pub_key];
        var new_data = Buffer.concat(arr);
        const sign = crypto.createSign('SHA256');
        sign.write(new_data);
        sign.end();
        const signature = sign.sign(my_prv_key, 'hex');
        signature_buf = Buffer.from(signature, 'utf8');
        var arr2 = [signature_buf,my_pub_key];
        var whole_data = Buffer.concat(arr2);
        console.log(whole_data.length);
        client.write(whole_data);           
        // sendData(data_from_sv)

        setTimeout(function (){
            menu();
        }, 0); 
    });
}

function sendData(data) { 
    
}

function menu (){
    var lineRead = readlineSync.question("\n\nEnter option (1-Open, 2-Send, 3-Close, 4-Quit): ");

    switch(lineRead){
        case "1":
            openConnection();
            break;
        case "2":
            var data = readlineSync.question("Enter data to send: ");
            sendData(data);
            break;
        case "3":
            closeConnection();

            break;
        case "4":
            return;
            break;
        default:
            setTimeout(function (){
                menu();
            }, 0);
            break;
    
    }
}
 

setTimeout(function (){
    menu();
}, 0);
 

控制器部分:

var readlineSync = require("readline-sync");
var net = require("net");
const crypto = require('crypto');
var bsplit = require('buffer-split')
var host = "127.0.0.1";
var port = 9000;


client = new net.Socket();


client.on("error", function(err) {
    client.destroy();
    client = null;
    console.log("ERROR: Connection could not be opened. Msg : %s", err.message);
});

client.connect(port, host, function () {
    console.log("Connection opened succesfully");
});


// client.once("data", function (data_from_sv) {
//     sc_once_data = data_from_sv;
//     console.log("Recieved: %s", sc_once_data);
// });

client.on("data", function (data_from_sv) {
    console.log("Recieved: %s", data_from_sv);

});

谢谢。

【问题讨论】:

    标签: javascript node.js tcp


    【解决方案1】:

    您是否考虑过创建两个服务器对象?
    如下所示:

    const server1 = net.createServer(); 
    const server2 = net.createServer(); 
    
    server1.listen(9001, host, () => { 
        console.log(`TCP Client listening on ${host}:9001`); 
    }); 
    server2.listen(9002, host, () => { 
        console.log(`TCP Client listening on ${host}:9002`); 
    });
    

    这将侦听两个不同的 TCP 端口,即 9001 和 9002。或者我完全没有听懂您的问题?

    【讨论】:

      【解决方案2】:

      我已经尝试过了,但我无法处理来自两个客户端进行 TCP 通信的数据。然后,我切换到UDP。我几乎解决了我的问题。

      这是我的 UDP 代码,

      UDP 客户端:

      const crypto = require('crypto');
      const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
          modulusLength: 2048,
      });
        
      var my_public = publicKey;
      var my_private = privateKey;
      
      var udp = require('dgram');
      
      var port = 5550;
      var host = "0.0.0.0";
      
      // creating a client socket
      var client = udp.createSocket('udp4');
      
      var data_cnt = 0;
      var data;
      var usr1_pub_pem;
      var token;
      var time = 100;
      var sign_pub;
      
      client.on('message',function(msg, info){
          //console.log('Received %d bytes from %s:%d\n',msg.length, info.address, info.port);
          console.log('Data received from server : ' + msg.toString());
      
          if(data_cnt == 1){
              data_cnt++;
              var token_tot = msg.toString().split(",")
              usr1_pub_pem = token_tot[0];
              token = token_tot[1];
              var message = token + "," + client.address().address + "," + time + "," + my_public;
              const sign = crypto.createSign('SHA256');
              sign.update(message);
              sign.end();
              signature = sign.sign(my_private);
              sign_pub = signature.toString() + "," + my_public.toString();
              var sign_pub_buf = Buffer.from(sign_pub);
              console.log("sign_pub = ", sign_pub_buf);
              client.send(sign_pub_buf, port, host, function(error){
                  if(error){
                      client.close();
                  }
                  else{
                      console.log('Sign+Public_K has been sent to server !!!');
                  }
              });                
          }
          else if(data_cnt == 2){
              //sending msg
              client.send(msg, port, host, function(error){
                  data_cnt ++;
                  if(error){
                      client.close();
                  }
                  else{
                      console.log('New message has been sent to server !!!');
                  }
              });            
          };  
      });
      
      if(data_cnt == 0){
          //buffer msg
          data = Buffer.from('This is client');
          client.send(data, port, host, function(error){
              data_cnt ++;   
              if(error){
                  client.close();
              }
              else{
                  console.log('Initial message has been sent to server !!!');
              }
          });    
      }

      UDP SDN:

      var udp = require('dgram');
      
      var port = 5551;
      var host = "0.0.0.0";
      
      // creating a sdn socket
      var sdn = udp.createSocket('udp4');
      
      var data_cnt = 0;
      var data;
      
      var usr1_pub_pem;
      var token;
      
      sdn.on('message',function(msg, info){
          console.log('Received %d bytes from %s:%d\n',msg.length, info.address, info.port);
          console.log("data_cnt = ", data_cnt);
          if(data_cnt == 1){
              console.log('Data received from server : ' + msg.toString());
              //console.log("data_cnt = ", data_cnt);
              var token_tot = msg.toString().split(",");
              usr1_pub_pem = token_tot[0];
              token = token_tot[1];
              data_cnt++;
              console.log("data_cnt = ", data_cnt);
          }
          else if (data_cnt == 2){
              console.log('Data received from server : ' + msg.toString());
              data_cnt ++; 
              var sig_pub = msg.toString().split(",");
              var pub = sig_pub[0];
              var sig = sig_pub[1];
              //...
              //...
          }
      
      });
      
      if(data_cnt == 0){
          //buffer msg
          data = Buffer.from('This is SDN');
          sdn.send(data, port, host, function(error){
              data_cnt ++;   
              if(error){
                  sdn.close();
              }
              else{
                  console.log('Initial message has been sent to server !!!');
              }
          });    
      }

      UDP 服务器:

      //////////////////////////////////////////////////////////////////////////
      //////////////////////////     START        //////////////////////////////
      //////////////////////////////////////////////////////////////////////////
      const fs = require("fs");
      
      // Get the filenames of user1 directory
      dir_name = "../wallet/user1/";
      const user1_info_dir = fs.readdirSync(dir_name);             
      
      // Assign specific file names on them
      const user1_pub_file = dir_name + user1_info_dir[1];
      
      // Read .pem by using "pem-file" package
      const user1_pub_pem = fs.readFileSync(user1_pub_file)
      
      var dgram = require('dgram');
      const host = "0.0.0.0";
      
      var udp_cli_port = 5550;
      var address_cli;
      var cli_port;
      var cli_family;
      var cli_ipaddr;
      
      var udp_sdn_port = 5551;
      var address_sdn;
      var sdn_port;
      var sdn_family;
      var sdn_ipaddr;
      
      const crypto = require('crypto');
      var rand_buf = crypto.randomBytes(256);
      var rand_str = user1_pub_pem.toString() + "," + rand_buf.toString();
      
      
      var count_cli = 0;
      var count_sdn = 0;
      
      ////////////////////////////////////////////////////////////////////////////
      ////////////////////////      CLI PART        //////////////////////////////
      ////////////////////////////////////////////////////////////////////////////
      
      var udpsocket_cli = dgram.createSocket('udp4');
      udpsocket_cli.bind(udp_cli_port,host);
      
      udpsocket_cli.on('listening', function() {
          address_cli = udpsocket_cli.address();
          cli_port= address_cli.port;
          cli_family = address_cli.family;
          cli_ipaddr = address_cli.address;
          console.log("listening "+cli_ipaddr+" port::"+cli_port);
      });
      
      udpsocket_cli.on('message', function(msg, rinfo) {
          //console.log('Data received from client : ' + msg.toString());
          //console.log('Received %d bytes from %s:%d\n',msg.length, rinfo.address, rinfo.port);    
          //console.log("message received :: "+ msg +" address:: "+rinfo.address+ " port = "+ rinfo.port );
          //sending msg
          if(count_cli == 0){
              udpsocket_cli.send(rand_str, rinfo.port, host, function(error){
                  count_cli ++;
                  if(error) {
                      udpsocket_cli.close();
                  }
                  else {
                      console.log('Random number has been sent to CLIENT !!!');
                  }
              });        
          }
          else if (count_cli == 1){
              console.log('Data received from client : ' + msg);
              udpsocket_cli.send(msg, sdn_port, sdn_ipaddr, function(error){
                  console.log("sdn_port = ", sdn_port);
                  console.log("sdn_ipaddr = ", sdn_ipaddr);
                  count_cli ++;
                  if(error) {
                      udpsocket_cli.close();
                  }
                  else {
                      console.log('CLI --------> SDN');
                  }
              });        
          }
      });
      
      // emits when any error occurs
      udpsocket_cli.on('error',function(error){
          console.log('Error: ' + error);
          udpsocket_cli.close();
      });
      
      //emits after the udpsocket_cli is closed using udpsocket_cli.close();
      udpsocket_cli.on('close',function(){
          console.log('udpsocket_cli is closed !');
      });
      
      ////////////////////////////////////////////////////////////////////////////
      ////////////////////////      SDN PART        //////////////////////////////
      ////////////////////////////////////////////////////////////////////////////
      
      var udpsocket_sdn = dgram.createSocket('udp4');
      udpsocket_sdn.bind(udp_sdn_port,host);
      
      udpsocket_sdn.on('listening', function() {
          address_sdn = udpsocket_sdn.address();
          sdn_port= address_sdn.port;
          sdn_family = address_sdn.family;
          sdn_ipaddr = address_sdn.address;
          console.log("listening "+sdn_ipaddr+" port::"+sdn_port);    
      });
      
      udpsocket_sdn.on('message', function(msg, rinfo) {
          //console.log('Data received from client : ' + msg.toString());
          //console.log('Received %d bytes from %s:%d\n',msg.length, rinfo.address, rinfo.port);    
          //console.log("message received :: "+ msg +" address:: "+rinfo.address+ " port = "+ rinfo.port );
          //sending msg
          if(count_sdn == 0){
              udpsocket_sdn.send(rand_str, rinfo.port, host, function(error){
                  count_sdn ++;
                  if(error) { 
                      udpsocket_sdn.close();
                  }
                  else {
                      console.log('Random number has been sent to SDN!!!');
                  }
              });        
          };       
      });
      
      // emits when any error occurs
      udpsocket_sdn.on('error',function(error){
          console.log('Error: ' + error);
          udpsocket_sdn.close();
      });
      
      //emits after the udpsocket_sdn is closed using udpsocket_sdn.close();
      udpsocket_sdn.on('close',function(){
          console.log('udpsocket_sdn is closed !');
      });
      
      //////////////////////////////////////////////////////////////////////////
      //////////////////////////     END        ////////////////////////////////
      //////////////////////////////////////////////////////////////////////////

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-13
        • 2021-07-10
        • 1970-01-01
        • 2021-06-02
        • 1970-01-01
        • 2011-04-25
        • 2012-10-28
        相关资源
        最近更新 更多