使用Node.js监听多个TCP端口

时间:2020-05-15 02:33:20

标签: javascript node.js tcp

.--------。 .----------。 .----------。 |客户| ---> |服务器A | | Cntrller | '--------''----------''----------' .--------。 .----------。 .----------。 |客户| <-> |服务器A | <-> | Cntrller | '--------''----------''----------' .--------。 .----------。 |客户| ---------------------> | Cntrller | '--------''----------' .--------。 .----------。 |客户| <--------------------- | | Cntrller | '--------''----------'

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

但是,我必须侦听两个不同的端口,并且无法通过在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);

});

谢谢。

2 个答案:

答案 0 :(得分:1)

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

app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
    app.UseMiddleware();
});

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

答案 1 :(得分:0)

我已经尝试过了,但是我无法处理来自两个客户端的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        ////////////////////////////////
//////////////////////////////////////////////////////////////////////////