Node.js - TCP Socket
간단한 hello world
Class: net.Server 이벤트
'listening': server.listen()를 호출 후 서버가 바인드 되었을 때 발생. 'connection': 새로운 연결이 만들어지면 발생. 'close': 서버가 끊어지면 발생. 'error': 에러 발생. 이 이벤트 이후 'close' 이벤트가 직접 생성되는 경우도 있다.
Class: net.Socket 이벤트
'connect': 소켓 커넥션 확립이 성공했을 때 발생. 'data': 데이터를 받으면 발생. 'end': 상대방이 FIN 패킷을 보냈을 때 발생. 'timeout': 소켓이 타임아웃 하여 비활성화된 경우에 발생. 'drain': 쓰기 버퍼가 빈 경우에 발생. 'error': 에러가 발생했을 때. 'close' 이벤트는 이 이벤트 후에 직접 호출된다. 'close': 소켓이 완전하게 끊어진 경우에 생성된다. 인수 had_error는 boolean으로 소켓이 전송 에러로 끊어졌는지 나타낸다.
접속한 클라이언트에 지정된 메시지를 보낸다.
net = require('net');
var s = net.createServer();
s.addListener('connection', function (c) {
c.write('[tcp/ip] hello world!\n');
});
console.log('start tcp~~~');
s.listen(23452);
socket 에 이벤트 등록
var s = net.createServer( function(socket) {
socket.on('data', function(data)) {
.....
});
socket.on('end', function() {
.....
});
});
간단한 클라어언트
var net = require('net');
var client = new net.Socket();
client.setEncoding('utf8');
client.connect('3000', 'localhost', function(){
console.log('client-> connected to server');
client.write('Who needs a browser to communicate?');
});
process.stdin.resume();
process.stdin.on('data', function(data){
client.write(data);
});
client.on('data', function(data){
console.log('client-> ' + data);
});
client.on('close', function(){
console.log('client-> connection is closed');
});
접속한 클라이언트 관리
출처: http://egloos.zum.com/spectrum/v/5577613
var clients = [];
require('net').createServer(function(socket) {
socket.on("connect", function() {
clients.push(socket);
});
socket.on("close", function() {
clients.splice(clients.indexOf(socket), 1);
});
socket.on("data", function(data) {
var sender = this;
clients.forEach(function(client) {
if (client !== sender) client.write(data);
});
});
}).listen(1337,"0.0.0.0");
접속 후 통신하지 않는 클라이언트 연결 종료하기
idle socket은 setTimeout(milliseconds)로 traffic 이 없을 경우 connection을 종료할 수 있다.
var timeout=6000;
socket.setTimeout(timeout);
socket.on('timeout',function(){
socket.write('idle timeout..');
socket.end();
});
또는 다음과 같이 줄일 수 있다.
socket.setTimeout(6000,function(){
socket.end('idle time, disconnecting..');
});
keep-alive 설정
ACK flag를 가진 빈 TCP Packet을 보내서 connection을 유지할 수 있다.
socket.setKeepAlive(true);
packet을 보내는 주기를 지정 가능하다
socket.setKeepAlive(true,10000);
TCP Buffer의 전송 Delay 설정
socket.setNoDelay(true); 로 write시 데이터를 즉시 보내게 할 수 있다. (socket.setNoDelay(false); 로 해제)
listening client connections
host가 생략되면 모든 IP Address에서 들어온 connection을 받아들인다.
var port=4001;
var host='127.0.0.1';
server.listen(port,host);
closing server
server.close()
server.on('close',function(){
console.log('server closed');
});
socket.setEncoding(‘utf8’)
TCP Socket의 setEncoding() 메서드를 수행하면, ‘data’ Event 발생시 callback으로 들어오는 데이터(data), 즉 수신 데이터의 타입이 String으로 변경된다.
바이너리 데이터를 주고 받을 때는 ‘setEncoding()’를 사용하지 않아야 한다.
바이너리 데이터 파싱하기
C++ 에서는 아래의 데이터를 보낸다.
struct CTestData {
char a;
int b;
char c[15];
};
node.js쪽
client.on('data', function(data) {
chara = data.slice(0, 4);
intb = data.slice(4, 8);
charc = data.slice(8, 24);
console.log('char a :', chara.toString('utf-8'));
console.log('int b :', intb.readUInt8());
console.log('char c :', charc.toString('utf-8'));
Buffer를 사용하여 바이너리 데이터 보내기
var net = require('net');
var buffer = new Buffer(3);
buffer.writeUInt8(0x01, 0);
buffer.writeUInt8(0x02, 1);
buffer.writeUInt8(0x03, 2);
var client = net.connect(8000, "127.0.0.1", function() {
client.write(buffer);
});
참고
이 글은 2019-04-17에 작성되었습니다.