LoginSignup
23
23

More than 5 years have passed since last update.

はじめてのプロセス間通信

Last updated at Posted at 2014-05-17

はじめに

「Node.js入門」を少し読みましたので、そのことを少し書きます。基本的なことはネットで見つけることができますので、この記事では「9.4 TCPエコーサーバ・クライアントの実装」のサンプルコードを少し変更して、クライアント間でデータを送受信できるか試してみたことを紹介します。流れとしては、ソースコードを紹介して、試し方を紹介して、試してみた感想になります。

必要なファイルは二つです。server.jsclient.jsです。(テキストで紹介されているファイル名とは違うファイル名です。)

サーバ側(常駐プロセス)

ソースコードのみの紹介になります。

var net = require('net');

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

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

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

var clients = {};

function chomp(raw_text)
{
  return raw_text.replace(/(\n|\r)+$/,'');
}

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

  var data = '';
  var newline = /\r\n|\n/;
  socket.on('data', function(chunk) {
    var k = chunk.toString();
    if (newline.test(k)) {
      k = chomp(k);
      clients['127.0.0.1:' + k].writeData('test data\n');
      k ='';
    }
  });

  socket.on('end', function(socket) {
    console.log('Connection End(' + status + ') - ' + key);
    delete clients[key];
  });
});

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

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

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

server.listen(11111, '127.0.0.1');
// vim: set sw=2 sts=2 et :

クライアント側(非常駐プロセス)

こちらもソースコードのみの紹介になります。

var net = require('net');

var options = {};
options.host = process.argv[2];
options.port = process.argv[3];

var client = net.connect(options);

client.on('error', function(e) {
  console.error('Connection Failed - ' + options.host + ':' + options.port);
  console.error(e.message);
});

client.on('connect', function() {
  console.log('Connection - ' + options.host + ':' + options.port);
});

process.on('SIGINT', function() {
  console.log('Connction Closed - ' + options.host + ':' + options.port);
  client.end();
});

process.stdin.on('data', function(data) {
  process.stdout.write('[S] ' + data);
  client.write(data);
});

client.on('data', function(chunk) {
  process.stdout.write(chunk.toString());
});

client.on('end', function(had_error) {
  console.log('Connction End - ' + options.host + ':' + options.port);
});

client.on('close', function() {
  console.log('Client Closed');
  process.exit(0);
});

試し方

ターミナルが三つ必要になります。

まず、一つ目のターミナルでサーバを起動します。

$ node server.js

次に、二つ目のターミナルでクライアントからサーバに接続します。第2引数にサーバのIPアドレス、第3引数にサーバのポート番号を指定します。

$ node client.js 127.0.0.1 11111

クライアント間でデータを送受信させたいので、もう一つクライアントが必要です。なので、三つ目のターミナルでもクライアントからサーバに接続します。

$ node client.js 127.0.0.1 11111

この段階で一つ目のターミナルを確認すると、二つ目のターミナルのクライアントのポート番号と三つ目のターミナルのクライアントのポート番号を確認できます。

Connection Start(1/3) - 127.0.0.1:49238
Connection Start(2/3) - 127.0.0.1:49239

さて、いよいよです。

一方のクライアントでもう一方のクライアントのポート番号を入力してみましょう。

49239

もう一方のクライアントを確認してみましょう。

[R] test data

クライアント間でデータを送受信できました。

まとめ

呆れた顔が目に浮かびます。いまどきのSocket.IOを使えばチャットを実装できるそうです。そういう技術がそろっている時代に、このような実装に挑戦して意味があるのでしょうか?そういう疑問もあるかもしれませんが、できそうだと思ったら、試してみたくなってしまったのです。

試してみて気付いたことはいくつかあります。一つは、サーバ側にクライアント間の通信用のプロトコルを実装すれば、もう少しマシな通信が実装できそうだということ。もう一つは、複数の機械を制御するためには、プロセス間通信みたいな仕組みが必要そうだということ。ちょっとした気付きでしたが、有意義な経験だったと思います。

23
23
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
23
23