나만의 작은 도서관

[TIL] 240701 캠프 78일차: read ECONNRESET 오류, slice(), 백틱과 바이트배열 console.log 본문

Today I Learn

[TIL] 240701 캠프 78일차: read ECONNRESET 오류, slice(), 백틱과 바이트배열 console.log

pledge24 2024. 7. 1. 21:51

오늘 배운 내용                                     

read ECONNRESET 오류 

read ECONNRESET이라는 오류가 ctrl+c를 통해 서버나 클라이언트를 강제종료 했을때 net모듈을 이용한 TCP서버에서 발생하였다. 그래서 이 오류가 치명적인 오류인지 확인할 필요가 있었고, 구글링을 해본 결과, 해당 오류는 다음과 같았다.

read ECONNRESET는 TCP conversation에서 한 쪽의 갑자기 닫혔을 때 발생하는 오류이다.

즉, ctrl+c를 통해 강제로 닫아 생긴 오류였고, 크게 걱정할 필요가 없었던 오류였다. 

 

VSCode 사이드바에서 열린 모든 폴더 접는 단축키

TCP서버를 구축하다보면 여기저기서 폴더를 열어 점점 열려있는 폴더들이 많아져 폴더들의 간격이 점점 벌어지게 되는데, 이게 날이 갈수록 상당히 불편하게 작용하였다. 그래서 해당하는 단축키가 있나 찾아보았더니 ctrl+ left arrow를 누르면 전부 접힌다는 것을 알게되었다. 실제로 사용해보니 아주 편해서 자주 사용할 듯 하다.

slice()

slice() 함수는 배열로부터 특정 범위를 복사한 값들을 담고 있는 새로운 배열을 만드는데 사용합니다. 첫번째 인자로 시작 인덱스(index), 두번째 인자로 종료 인덱스를 받으며, 시작 인덱스부터 종료 인덱스까지 값을 복사하여 반환합니다.

두번째 인자를 넘기지 않으면, 시작 인덱스가 가리키는 값부터 배열의 마지막 값까지 모두 복사해줍니다.

nums = Array(20).fill().map((_, i) => i)
console.log(nums.slice(5, 10)); // [5, 6, 7, 8, 9]
console.log(nums.slice(10)) // [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

 

백틱으로 console.log를 찍으면 바이트 배열은 문자열로 변환된다.

console.log를 찍어보던 중, 이상한 점을 발견했다. 전송받은 데이터가 Hello라는 문자열을 바이트 배열로 인코딩한 데이터라면 디코딩하기 전까지 해당 데이터를 출력시 <Buffer 48 65 6c 6c 6f>와 같이 출력될 것을 예상할 수 있다. 나또한 자명하다 생각했었고, 그렇게 백틱에 넣어 보다 편리하게 console.log문을 작성해야겠다 생각했다. 그런데, 출력된 결과는 Hello가 나오는 것이였다! 알고보니 백틱으로 감싸면 해당 데이터가 대응하는 문자열로 치환되는 듯 했고 나는 여기서 치환되는 범위가 바이트배열도 포함될 것이라는 것을 생각하지 못했던 것이다...!

// 서버가 클라이언트에게 "Hello"라는 문자열을 바이트배열로 수신받았을 경우
server.on('data', (data) => {
  console.log(`Received data: ${data}`); // Hello
  console.log('Received data:', data); // <Buffer 48 65 6c 6c 6f>

}

 

오늘의 Trouble Shooting                  

Problem 1. 클라이언트의 localPort가 정의되지 않음(undefined)

간단한 TCP Echo서버를 복습하며 client.js에서 클라이언트 소켓의 지정된 포트번호를 알고 싶었다. 그래서 client.js의 가장 맨 아래에 console.log(client.localPort);를 넣어서 실행해보았다. 하지만 결과값은 undefined가 나왔고, 연결을 하는 코드가 한참 위에 있었음에도 undefinde가 나오는 것에 의아했다. 해당 client.js 코드는 다음과 같다.

// client.js
import net from 'net';

const HOST = 'localhost';
const PORT = 5555;

const client = new net.Socket();


client.connect(PORT, HOST, () => {
    console.log('Connected to server');
})

client.on('data', (data) => {
    console.log(data);
})

// 서버가 연결을 끊었을 때 트리거 발동
client.on('close', () => {
    console.log('Connection closed');
})

client.on('error', (err) => {
    console.error('Client error: ', err);
});

console.log(client.localPort);

Solve. 연결을 시도하는 client.connect() 함수안으로 console.log문 이동

client.connect()함수는 연결을 시도하는 함수로, 연결이 성공해야지만 정의한 콜백함수를 실행하는 비동기 함수이다. 따라서, 코드가 순차적으로 진행되지 않을 수 있으며, 가장 아래에 console.log가 있어도 connect()함수보다 먼저 실행될 수 있다. 즉, 아직 연결이 되지 않아 localPort가 정의되지 않았고, 그래서 undefined가 출력된 것이었다.

localPort에 대한 정보를 알고 싶다면 알맞은 자리는 바로 콜백함수 내부에 위치하는 것이다. 

// client.js
import net from 'net';

const HOST = 'localhost';
const PORT = 5555;

const client = new net.Socket();


client.connect(PORT, HOST, () => {
    console.log('Connected to server');
    console.log(client.localPort); // 콜백함수 내부로 이동.
})

client.on('data', (data) => {
    console.log(data);
})

// 서버가 연결을 끊었을 때 트리거 발동
client.on('close', () => {
    console.log('Connection closed');
})

client.on('error', (err) => {
    console.error('Client error: ', err);
});

 

 

오늘 한 일                                       

더보기
  • TCP echo서버 설명하면서 클론코딩하기 -완-
  • TCP 서버 설명하면서 클론코딩하기 40%