Node.js net.createConnection() 実践:複数クライアント接続とタイムアウト設定
2025-04-26
基本的な説明
- UNIXドメインソケット接続
- UNIXベースのシステムでは、ファイルパスを指定することで、ローカルプロセス間の通信にUNIXドメインソケットを使用できます。
- これは、同じマシン上で動作するプロセス間の高速な通信を可能にします。
- TCP接続
net.createConnection()
は、IPアドレスとポート番号を指定することで、リモートサーバーとのTCP接続を確立します。- これは、クライアントがサーバーと通信する必要がある場合に非常に便利です。たとえば、HTTPクライアントやデータベースクライアントなどがこれを使用します。
関数の構文
net.createConnection(options[, connectListener])
net.createConnection(port[, host][, connectListener])
net.createConnection(path[, connectListener])
connectListener
: 接続が確立されたときに呼び出されるコールバック関数。path
: UNIXドメインソケットのパス。host
: 接続先のホスト名またはIPアドレス。port
: 接続先のポート番号。options
: 接続オプションを含むオブジェクト。
例
TCP接続の例
const net = require('net');
const client = net.createConnection({ port: 8080, host: '127.0.0.1' }, () => {
console.log('サーバーに接続しました!');
client.write('Hello, server!\\r\\n');
});
client.on('data', (data) => {
console.log(`サーバーからのデータ: ${data.toString()}`);
client.end();
});
client.on('end', () => {
console.log('サーバーとの接続が終了しました。');
});
client.on('error', (err) => {
console.error(`エラーが発生しました:${err}`);
});
この例では、net.createConnection()
を使用してローカルホストの8080ポートに接続し、データを送受信しています。
UNIXドメインソケット接続の例
const net = require('net');
const client = net.createConnection({ path: '/tmp/my_socket' }, () => {
console.log('UNIXドメインソケットに接続しました!');
client.write('Hello, UNIX socket!\\r\\n');
});
client.on('data', (data) => {
console.log(`UNIXソケットからのデータ: ${data.toString()}`);
client.end();
});
client.on('end', () => {
console.log('UNIXソケットとの接続が終了しました。');
});
client.on('error', (err) => {
console.error(`エラーが発生しました:${err}`);
});
この例では、/tmp/my_socket
にあるUNIXドメインソケットに接続しています。
net.createConnection()
は、Node.jsでTCPまたはUNIXドメインソケット接続を確立するための重要な関数です。これを使用することで、クライアントはサーバーと通信し、データを送受信できます。
接続拒否 (Connection Refused)
- UNIXドメインソケットの場合
ソケットファイルが存在するか、正しいパスが指定されているか確認してください。 - トラブルシューティング
- サーバーが正しく起動しているか確認してください。
- ポート番号とホスト名/IPアドレスが正しいか確認してください。
- ファイアウォール設定を確認し、接続を許可してください。
- サーバー側のログを確認し、エラーメッセージがないか確認してください。
- 原因
指定されたホストまたはポートでサーバーが実行されていない、またはサーバーが接続を受け付けていない可能性があります。ファイアウォールが接続をブロックしている可能性もあります。 - エラーメッセージの例
Error: connect ECONNREFUSED 127.0.0.1:8080
接続タイムアウト (Connection Timeout)
- トラブルシューティング
- サーバーが応答しているかpingコマンドなどで確認してください。
- ネットワーク接続を確認してください。
- 接続タイムアウト時間を調整してみてください。
net.createConnection()
のoptions
オブジェクトでtimeout
プロパティを設定できます。 - サーバー側で処理に時間がかかっている可能性もあるため、サーバー側のパフォーマンスも確認してください。
- 原因
サーバーが応答しない、またはネットワーク接続が遅延している可能性があります。 - エラーメッセージの例
Error: connect ETIMEDOUT 127.0.0.1:8080
アドレスが使用中 (Address Already in Use)
- トラブルシューティング
- 別のプロセスがポートを使用していないか確認してください。
netstat
コマンドやlsof
コマンドを使用して、ポートを使用しているプロセスを特定できます。 - 別のポートを使用するようにサーバーを設定してください。
- サーバーを再起動する前に、以前のプロセスが完全に終了していることを確認してください。
- 別のプロセスがポートを使用していないか確認してください。
- 原因
指定されたポートが別のプロセスによって使用されています。 - エラーメッセージの例
Error: listen EADDRINUSE :::8080
(サーバー側で発生)
ソケットエラー (Socket Errors)
- EPIPE
パイプが壊れている。クライアントかサーバーの接続が切れた状態で、書き込みをすると発生します。 - トラブルシューティング
- サーバー側のログを確認し、エラーメッセージがないか確認してください。
- ネットワーク接続が安定しているか確認してください。
- クライアントとサーバーの両方で、エラー処理を適切に行っているか確認してください。
- クライアントとサーバー間の通信プロトコルが一致しているか確認してください。
- 原因
接続が予期せず閉じられた、またはソケットでエラーが発生しました。 - エラーメッセージの例
Error: read ECONNRESET
,Error: write EPIPE
ホスト名解決エラー (Hostname Resolution Error)
- トラブルシューティング
- ホスト名が正しいか確認してください。
- DNSサーバーが正しく設定されているか確認してください。
- ネットワーク接続を確認してください。
- 原因
指定されたホスト名をIPアドレスに解決できませんでした。 - エラーメッセージの例
Error: getaddrinfo ENOTFOUND example.com
- ドキュメントを読む
Node.jsのnet
モジュールのドキュメントを読んで、関数の使い方やエラー処理について理解を深めてください。 - 単純なテストを行う
問題を特定するために、単純なクライアントとサーバーを作成してテストしてみてください。 - ネットワークツールを使用する
ping
,traceroute
,netstat
,tcpdump
などのネットワークツールを使用して、ネットワーク接続やサーバーの状態を確認してください。 - ログを確認する
クライアントとサーバーの両方のログを確認し、エラーメッセージや警告がないか確認してください。 - エラーメッセージをよく読む
エラーメッセージには、問題の原因に関する重要な情報が含まれています。
基本的なTCPクライアント
const net = require('net');
const client = net.createConnection({ port: 8080, host: '127.0.0.1' }, () => {
console.log('サーバーに接続しました!');
client.write('Hello, server!\\r\\n'); // サーバーにデータを送信
});
client.on('data', (data) => {
console.log(`サーバーからのデータ: ${data.toString()}`); // サーバーからのデータを受信
client.end(); // 接続を終了
});
client.on('end', () => {
console.log('サーバーとの接続が終了しました。');
});
client.on('error', (err) => {
console.error(`エラーが発生しました:${err}`);
});
client.on('error', ...)
でエラー処理を行います。client.end()
で接続を終了します。client.write()
でサーバーにデータを送信し、client.on('data', ...)
でサーバーからのデータを受信します。net.createConnection()
でサーバーへの接続を確立し、接続が成功するとconnect
イベントが発生し、コールバック関数が実行されます。- このコードは、ローカルホストの8080ポートに接続する基本的なTCPクライアントです。
タイムアウト設定
const net = require('net');
const client = net.createConnection({ port: 8080, host: '127.0.0.1', timeout: 5000 }, () => {
console.log('サーバーに接続しました!');
client.write('Hello, server!\\r\\n');
});
client.on('data', (data) => {
console.log(`サーバーからのデータ: ${data.toString()}`);
client.end();
});
client.on('timeout', () => {
console.log('接続がタイムアウトしました。');
client.end();
});
client.on('error', (err) => {
console.error(`エラーが発生しました:${err}`);
});
- この例では、5000ミリ秒(5秒)以内に接続が確立されない場合、
timeout
イベントが発生します。 options
オブジェクトにtimeout
プロパティを追加することで、接続タイムアウトを設定できます。
UNIXドメインソケットクライアント
const net = require('net');
const socketPath = '/tmp/my_socket'; // UNIXドメインソケットのパス
const client = net.createConnection({ path: socketPath }, () => {
console.log('UNIXドメインソケットに接続しました!');
client.write('Hello, UNIX socket!\\r\\n');
});
client.on('data', (data) => {
console.log(`UNIXソケットからのデータ: ${data.toString()}`);
client.end();
});
client.on('end', () => {
console.log('UNIXソケットとの接続が終了しました。');
});
client.on('error', (err) => {
console.error(`エラーが発生しました:${err}`);
});
- この例では、
/tmp/my_socket
にあるUNIXドメインソケットに接続します。 options
オブジェクトにpath
プロパティを指定することで、UNIXドメインソケットに接続できます。
const net = require('net');
for (let i = 0; i < 3; i++) {
const client = net.createConnection({ port: 8080, host: '127.0.0.1' }, () => {
console.log(`クライアント ${i + 1} が接続しました!`);
client.write(`クライアント ${i + 1} からのメッセージ\\r\\n`);
});
client.on('data', (data) => {
console.log(`クライアント ${i + 1} が受信: ${data.toString()}`);
client.end();
});
client.on('end', () => {
console.log(`クライアント ${i + 1} が切断しました。`);
});
client.on('error', (err) => {
console.error(`クライアント ${i + 1} でエラーが発生しました:${err}`);
});
}
- 各クライアントは、異なるメッセージをサーバーに送信し、サーバーからの応答を受信します。
- このコードは、ループを使用して複数のクライアントを同時にサーバーに接続する例です。
net.connect()
- 構文と使い方は
net.createConnection()
と全く同じです。 - コードの可読性を向上させるために、より直感的な
net.connect()
を使用することもできます。 net.connect()
はnet.createConnection()
のエイリアスであり、機能は全く同じです。
const net = require('net');
const client = net.connect({ port: 8080, host: '127.0.0.1' }, () => {
console.log('サーバーに接続しました!');
// ...
});
socket.connect()
net.createConnection()
またはnet.connect()
は内部的にnet.Socket
オブジェクトを作成してconnect()
メソッドを呼び出しています。net.Socket
オブジェクトは、ソケット通信をより細かく制御する必要がある場合に便利です。net.Socket
オブジェクトを作成し、そのconnect()
メソッドを使用する方法です。
const net = require('net');
const socket = new net.Socket();
socket.connect({ port: 8080, host: '127.0.0.1' }, () => {
console.log('サーバーに接続しました!');
socket.write('Hello, server!\\r\\n');
});
socket.on('data', (data) => {
console.log(`サーバーからのデータ: ${data.toString()}`);
socket.end();
});
// ...
net.Socket
オブジェクトを使用すると、socket.setTimeout()
やsocket.setNoDelay()
などのメソッドを使用して、ソケットの動作をより細かく制御できます。
HTTP/HTTPSモジュール
http.request()
やhttps.request()
を使用して、HTTP/HTTPSリクエストを送信できます。- これらのモジュールは、HTTP/HTTPSプロトコルを抽象化し、より高レベルなAPIを提供します。
- HTTPまたはHTTPS通信を行う場合、
net
モジュールを直接使用する代わりに、http
またはhttps
モジュールを使用するのが一般的です。
const http = require('http');
const options = {
hostname: '127.0.0.1',
port: 8080,
path: '/api/data',
method: 'GET'
};
const req = http.request(options, (res) => {
console.log(`ステータスコード: ${res.statusCode}`);
res.on('data', (chunk) => {
console.log(`データ: ${chunk}`);
});
});
req.on('error', (err) => {
console.error(`エラー: ${err}`);
});
req.end();
- HTTP/HTTPS通信では、
net
モジュールを直接使用するよりも、http
またはhttps
モジュールを使用する方がコードが簡潔になり、エラー処理も容易になります。
- WebSocketは、双方向のリアルタイム通信を可能にするプロトコルであり、チャットアプリケーションやリアルタイムゲームなどで使用されます。
- WebSocket通信を行う場合、
ws
などのWebSocketクライアントライブラリを使用するのが一般的です。
const WebSocket = require('ws');
const ws = new WebSocket('ws://127.0.0.1:8080');
ws.on('open', () => {
console.log('WebSocket接続が確立されました!');
ws.send('Hello, WebSocket server!');
});
ws.on('message', (data) => {
console.log(`サーバーからのメッセージ: ${data}`);
});
ws.on('close', () => {
console.log('WebSocket接続が閉じられました。');
});
- WebSocket通信では、
net
モジュールを直接使用するよりも、WebSocketクライアントライブラリを使用する方がコードが簡潔になり、WebSocketプロトコルの詳細を意識する必要がなくなります。
- WebSocket通信では、WebSocketクライアントライブラリを使用するのが一般的です。
- HTTP/HTTPS通信では、
http
またはhttps
モジュールを使用するのが一般的です。 net.Socket
オブジェクトを使用すると、ソケット通信をより細かく制御できます。net.connect()
はnet.createConnection()
のエイリアスです。