====== node.js 에코 서버와 클라이언트 제작해보기 ====== node.js 기반의 에코 서버, 파이썬 기반으로 대응되는 간단한 콘솔 클라이언트를 제작해봅니다. ===== 시놉시스 ===== ==== 서버 ==== - 클라이언트가 접속하면 접속하였다는 메시지를 출력합니다. - 클라이언트로부터 메시지를 받으면 받은 메시지를 그대로 출력하고, 클라이언트로 되돌려 보냅니다. - 클라이언트로부터 접속이 종료되면 종료 메시지를 출력합니다. ==== 클라이언트 ==== - 서버에 접속하면 접속했다는 메시지를 출력합니다. - 서버에 메시지를 보냅니다. 받은 메시지는 서버에 전달되었다가, 그대로 서버로부터 전달받습니다. - 클라이언트는 간단하게 C, 파이썬으로 구현해봅니다. ===== 서버측 구현===== // 필요한 객체를 선언합니다. var net = require('net'); var port = 9000; // 소켓에 필요한 핸들러는 이 곳에 미리 선언합니다. function server_handler(socket) { socket.on('connect', onSocketConnect); //socket.on('data', onSocketData); socket.on('end', onSocketEnd); socket.on('timeout', onSocketTimeOut); socket.on('drain', onSocketDrain); socket.on('error', onSocketError); socket.on('close', onSocketClose); // socket에 효과적으로 접근하기 위해서는 이 방법이 효과적입니다. socket.on('data', function (buffer) { onSocketData(socket, buffer) }); } // net.Socket event handlers function onSocketConnect() { console.log('onSocketConnect: connection established'); } function onSocketData(socket, buffer) { var msg = 'ECHO: ' + buffer; console.log('onSocketData: data received'); process.stdout.write(msg); if(socket.write(msg)) console.log('onSocketData: data echoed successfully'); else console.log('onSocketData: some error occured :('); } // emitted when the other side of the socket sends a FIN packet function onSocketEnd() { console.log('onSocketEnd: a client sent a FIN packet.'); } function onSocketTimeOut() { console.log('onSocketTimeOut: called.'); } // when the write buffer becomes empty function onSocketDrain() { console.log('onSocketDrain: called.'); } function onSocketError(err) { console.log('onSocketError: called.'); } function onSocketClose(had_error) { console.log('onSocketClose: connection closed.'); if(had_error) { console.log('onSocketClose: some error happend :('); } else { console.log('onSocketClose: no error :)'); } } // net.Server event handler function onServerListening() { console.log('onServerListening: listening on port ' + port); console.log('Press \'x\' to exit...'); } function onServerConnection(socket) { var ip = socket.remoteAddress; var port = socket.remotePort; console.log('onServerConnection: connection received from '+ip+':'+port); } function onServerClose() { console.log('onServerClose: server closed'); process.exit(0); } function onServerError(err) { console.log('onServerError: called'); } function onStdinData(server, data) { console.log('onStdinData: '+data); console.log('onStdinData: length '+data.length); if(data == 'x\n') { console.log('onStdinData: termination command received'); server.close(); process.exit(0); } } function onStdinEnd() { console.log('onStdinEnd: called'); } //////////////////////////////////////////////////////////////////////////////// // Beginning // argument parsing if (process.argv.length != 3) { console.log('Usage: node echo_server.js '); process.exit(0); } else { port = process.argv[2] } // 서버 생성 var server = net.createServer(server_handler); // 서버의 이벤트를 설정합니다. // server.on('data', ); server.on('listening', onServerListening); server.on('connection', onServerConnection); server.on('close', onServerClose); server.on('error', onServerError); // 서버는 대기 server.listen(port); // stdin 활성화 process.stdin.resume(); process.stdin.on('data', function(data){onStdinData(server, data);}); process.stdin.on('end', onStdinEnd); ==== 사용법 ==== node echo_server.js 9000 ===== 클라이언트 측 스크립트 ===== // 필요한 객체를 선언합니다. var net = require('net'); // net.Socket event handlers function onSocketConnect() { console.log('onSocketConnect: connection established'); } function onSocketData(socket, buffer) { console.log('onSocketData: data received'); process.stdout.write(buffer); } // emitted when the other side of the socket sends a FIN packet function onSocketEnd() { console.log('onSocketEnd: a client sent a FIN packet.'); } function onSocketTimeOut() { console.log('onSocketTimeOut: called.'); } // when the write buffer becomes empty function onSocketDrain() { console.log('onSocketDrain: called.'); } function onSocketError(err) { console.log('onSocketError: called.'); } function onSocketClose(had_error) { console.log('onSocketClose: connection closed.'); if(had_error) { console.log('onSocketClose: some error happend :('); } else { console.log('onSocketClose: no error :)'); } process.exit(0); } function onStdinData(socket, data) { socket.write(data); console.log('onStdinData: data sent'); } //////////////////////////////////////////////////////////////////////////////// // Beginning // argument parsing if (process.argv.length != 4) { console.log('Usage: node echo_client.js '); process.exit(0); } var host = process.argv[2]; var port = process.argv[3]; // 소켓 생성 var options = {'port': port, 'host': host}; var socket = net.createConnection(options); // 핸들러 설정 socket.on('connect', onSocketConnect); socket.on('end', onSocketEnd); socket.on('timeout', onSocketTimeOut); socket.on('drain', onSocketDrain); socket.on('error', onSocketError); socket.on('close', onSocketClose); // socket에 효과적으로 접근하기 위해서는 이 방법이 효과적입니다. socket.on('data', function (buffer) { onSocketData(socket, buffer) }); // stdin 활성화 process.stdin.resume(); process.stdin.on('data', function(data){onStdinData(socket, data);}); ==== 사용법 ==== node echo_client.js 127.0.0.1 9000