LoginSignup
34
32

More than 5 years have passed since last update.

1台のPCで大量の接続テストをしたい

Posted at

ミッション

1000台分の接続テストがしたい。

下準備

Linuxのシェルスクリプトで
一枚のNICに大量のIPアドレスを割り当てる
Windowsのバッチファイルで
一枚のNICに大量のIPアドレスを割り当てる(Windowsバッチ編)

実装

とある内製サーバーアプリケーションのテストで多数の接続テストがしたい。
でも、そんなにクライアントを用意できないので、仮想クライアントを用意しようというのが始まりです。
一枚のNICに大量のIPアドレスを割り付けて、複数のIPアドレスから繋いでいる風にみせようかと。
とりあえずNode.jsでサーバーとクライアントのアプリのサンプルを作って見ました。

サーバーは待ち受けてエコーしているだけです。

server.js
var net = require('net');
var readline = require('readline');
require('date-utils');

var server = net.createServer();
server.maxConnections = 2000;

function Client(socket){
  this.socket = socket;
}

Client.prototype.writeData = function(d){
  var socket = this.socket;
  if(socket.writable){
    var key = socket.remoteAddress + ':' + socket.remotePort;
    log('[' + key + '] - ' + d);
    socket.write('[R]' + d);
  }
};

function log(log) {
  var date = new Date();
  var formatted = date.toFormat("YYYY/MM/DD HH24:MI:SS");
  process.stdout.write( formatted + ":" + log + '\r\n');
}

var clients = {}

server.on('connection', function(socket){
  var status = server.connections + '/' + server.maxConnections;
  var key = socket.remoteAddress + ':' + socket.remotePort;
  log('Connection Start(' + status + ') - ' + key);
  clients[key] = new Client(socket);
});

server.on('connection', function(socket){
  var data = '';
  var newline = /\r\n|\n/;
  socket.on('data', function(chunk){
    data += chunk.toString();
    var key = socket.remoteAddress + ':' + socket.remotePort;
    if(newline.test(data)){
      clients[key].writeData(data);
      data = '';
    }
  });
});

server.on('connection', function(socket){
  var key = socket.remoteAddress + ':' + socket.remotePort;
  socket.on('end', function(){
    var status = server.connections + '/' + server.maxConnections;
    log('Connection End(' + status + ') - ' + key);
    delete clients[key];
  });
});

server.on('close', function(){
  log('Server Closed');
});

server.listen(8778, '172.21.0.228', function(){
  var addr = server.address();
  log('Listening Start on Server - ' + addr.address + ':' + addr.port);
});

var rl = readline.createInterface(process.stdin, process.stdout);
rl.on('SIGINT', function(){
  for(var i in clients){
    var socket = clients[i].socket;
    socket.end();
  }
  server.close();
  rl.close();
});

クライアントはlocalAddressを変えながら繋いでいます。

client.js
var net = require('net');
require('date-utils');

function log(log) {
  var date = new Date();
  var formatted = date.toFormat("YYYY/MM/DD HH24:MI:SS");
  process.stdout.write( formatted + ":" + log + '\r\n');
}

var adr3Array=[], adr4Array=[];
for(var i=40; adr3Array.push(i++) < 50;);
for(var j=0; adr4Array.push(j++) < 100;);

function clientFunc(local) {
  var options = {
    port: 8778,
    host: '172.21.0.228',
    localAddress: local
  };
  var client = net.connect(options);
  client.on('error', function(e){
    log(local + ':Connection Failed');
    log(e.message);
  });

  client.on('connect', function(){
    log(local + ':Connected');
  });

  client.setTimeout(1000);
  client.on('timeout', function(){
    var str = 'Hello World\r\n';
    log(local + ":" + str);
    client.write(str);
  });

  client.on('data', function(chunk){
    log(local + ":" + chunk.toString());
  });

  client.on('end', function(had_error){
    client.setTimeout(0);
    log(local + ':Connetion End');
  });

  client.on('close', function(){
    log(local + ':Client Closed');
  });
};


adr3Array.forEach(function(adr3) {
  adr4Array.forEach(function(adr4) {
    clientFunc('172.21.'+adr3+'.'+adr4);
  });
});

確認

サーバー側のログ。

2016/04/29 13:28:58:[172.21.47.28:59911] - Hello World
2016/04/29 13:28:58:[172.21.47.29:59912] - Hello World
2016/04/29 13:28:58:[172.21.47.30:59913] - Hello World
2016/04/29 13:28:58:[172.21.47.31:59914] - Hello World
2016/04/29 13:28:58:[172.21.47.32:59915] - Hello World
2016/04/29 13:28:58:[172.21.47.33:59916] - Hello World
2016/04/29 13:28:58:[172.21.47.34:59917] - Hello World
2016/04/29 13:28:58:[172.21.47.35:59918] - Hello World
2016/04/29 13:28:58:[172.21.47.36:59919] - Hello World
2016/04/29 13:28:58:[172.21.47.37:59920] - Hello World

あとはクライアント側の実装を、実際のサーバーの電文仕様に合わせていこう。
それが大変なわけだが・・・。

34
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
32