Node.js 에서 기본 모듈인 Net 을 사용하여 TCP 핑을 보내는 방법입니다.
다른 방법은 아래의 글을 참조하세요.
와니네 블로그 - Node.js 에서 TCP/UDP/ICMP 핑 보내기 (Pingus 모듈 사용)
와니네 블로그 - Node.js 에서 UDP 핑 보내기 (기본 모듈 사용)
TCP 핑 보내기
Node.js 의 기본 모듈 중 하나인 Net 모듈을 사용하여 호스트의 특정 TCP 포트 연결을 확인할 수 있습니다.
1. Net 모듈을 임포트합니다.
import net from 'net';
2. 연결하는 데 사용할 소켓을 하나 만듭니다.
const socket = new net.Socket();
3. 소켓에 이벤트 리스너들을 등록합니다.
3.1. 소켓 연결이 수립되었을 때 'connect' 이벤트가 호출됩니다.
socket.on('connect', () => {
const ip = socket.remoteAddress;
console.log(`소켓 연결됨: ${ip}`);
});
3.2. 소켓이 완전히 닫겼을 때 'close' 이벤트가 호출됩니다.
socket.on('close', (error) => {
console.log(`소켓 연결 종료`);
});
3.3. 소켓 연결 중 오류가 발생하면 'error' 이벤트가 호출됩니다.
socket.on('error', (error) => {
console.error('소켓 연결 오류:', error);
});
3.4. 설정된 시간동안 소켓 활동이 없으면 'timeout' 이벤트가 호출됩니다.
socket.setTimeout(2000); // 타임아웃 시간 2000ms로 설정
socket.on('timeout', () => {
console.error('소켓 타임아웃');
});
4. 원하는 호스트와 TCP 포트에 소켓 연결을 시도합니다.
socket.connect(80, 'example.com');
하나의 코드로 만들면 다음과 같습니다. 연결 가능 여부만 확인할 것이므로 타임아웃 이벤트 발생이 소켓을 제거하는 코드가 추가되어 있습니다.
import net from 'net';
const socket = new net.Socket();
// 연결됨
socket.on('connect', () => {
const ip = socket.remoteAddress;
console.log(`소켓 연결됨: ${ip}`);
});
// 연결 종료
socket.on('close', (hadError) => {
console.log(`소켓 연결 종료`);
});
// 오류
socket.on('error', (error) => {
console.error('소켓 연결 오류:', error);
});
// 타임아웃
socket.setTimeout(2000); // 타임아웃 시간 2000ms로 설정
socket.on('timeout', () => {
console.error('소켓 타임아웃');
socket.destroy();
});
socket.connect(80, 'example.com');
실행하면 연결이 수립된 뒤 아무 활동이 없으므로 타임아웃이 발생하고 연결이 종료됩니다.
// 콘솔 출력 결과
소켓 연결됨: 93.184.216.34
소켓 타임아웃
소켓 연결 종료
연결할 수 없는 호스트의 경우 연결이 수립되지 않고 타임아웃이 발생한 뒤 연결이 종료됩니다.
socket.connect(80, '10.1.2.3');
// 콘솔 출력 결과
소켓 타임아웃
소켓 연결 종료
알 수 없는 호스트이거나 연결 중 오류가 발생하였을 경우 'error' 이벤트가 발생한 뒤 연결이 종료됩니다.
socket.connect(80, 'notexisthost.notexist');
// 콘솔 출력 결과
소켓 연결 오류: Error: getaddrinfo ENOTFOUND notexisthost.notexist
at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:109:26) {
errno: -3008,
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'notexisthost.notexist'
}
소켓 연결 종료
사용하기 쉽게 하나의 함수로 만들면 다음과 같습니다.
import net from 'net';
function tcping(host, port = 80) {
const socket = new net.Socket();
let isConnected = false; // 연결 수립 여부 확인용
let ip = null;
let error = null;
return new Promise((resolve, reject) => {
// 연결됨
socket.on('connect', () => {
isConnected = true; // 연결 수립됨
ip = socket.remoteAddress; // 연결된 호스트의 IP
});
// 연결 종료
socket.on('close', (hadErr) => {
if (error) {
reject(error);
} else {
resolve(ip);
}
});
// 오류
socket.on('error', (err) => {
error = err;
});
// 타임아웃
socket.setTimeout(2000); // 타임아웃 시간 2000ms로 설정
socket.on('timeout', () => {
// 연결이 수립된 적 없이 오류 발생시 타임아웃 오류 처리
if (!isConnected) {
error = 'ETIMEDOUT';
}
socket.destroy();
});
socket.connect(port, host);
});
}
tcping('example.com', 80).then(console.log).catch(console.error);
실행하면 연결 수립 성공 시 호스트의 IP, 연결 실패 시 오류 메시지가 반환됩니다.
참조한 글