이 사이트의 실습은 자바스크립트를 켜야 움직입니다. 아래는 같은 내용을 글로 적은 것입니다.
기초개념 › 네트워크
연결을 맺는다는 것은 무엇이고, 연결 없이 보내면 어떻게 되는가
두 프로그램이 네트워크로 글자(바이트)를 주고받는 규칙에는 TCP와 UDP가 있습니다. TCP로 보내려면 보내는 쪽 프로그램이 먼저 "127.0.0.1의 9000번 포트에 연결한다"는 줄을 실행해 받는 쪽과 연결을 맺어야 합니다. 연결은 받는 쪽 프로그램이 그 포트를 열고 기다리고 있을 때만 맺어지고, 맺어진 뒤에 보낸 글자는 보낸 차례대로 도착합니다. UDP에는 연결하는 줄이 없습니다. 글을 보내는 줄마다 보낼 곳을 적어 그냥 던집니다. 이 실습은 보내는 방식을 TCP와 UDP로 바꾸고, 받는 쪽 프로그램을 있게도 없게도 하며, 보내는 쪽이 무엇을 받고 받는 쪽이 무엇을 받는지를 봅니다. 코드 칸은 실제 프로그램이 아니라 두 프로그램이 하는 일을 말로 적은 것이고, 9000이라는 번호는 예시입니다. 포트는 한 컴퓨터 안에서 프로그램을 구분하는 번호이고, 127.0.0.1 주소는 이 컴퓨터 자신을 가리킵니다.
실행으로 대조 · Node.js 24.18.0의 net·dgram으로 127.0.0.1에서 네 가지 조합을 실행해 대조
# 받는 쪽 프로그램 9000번 포트를 TCP로 열고 기다린다 # 보내는 쪽 프로그램 127.0.0.1의 9000번 포트에 TCP로 연결한다 글을 보낸다: "A" 글을 보낸다: "B" 글을 보낸다: "C"
보내는 쪽 프로그램과 받는 쪽 프로그램은 Node.js 24.18.0(Windows 11)의 net 모듈(TCP)과 dgram 모듈(UDP)로 만들어 127.0.0.1에서 실제로 실행했습니다. 코드 칸은 이 프로그램들의 소스가 아니라 각 프로그램이 하는 일을 말로 적은 것이고, 대조한 것은 그 줄들이 실제로 실행한 동작(받는 쪽이 포트를 열었는지와 프로토콜, 연결하는 호출이 있었는지, 보낸 글의 순서)과 같은지입니다. 네 가지 조합을 모두 조합마다 다섯 번씩 실행했고 다섯 번의 결과가 같았습니다. 대조한 것은 보내는 쪽이 받은 것(연결 성공 여부, 오류 코드, 오류 없이 끝난 보내기 횟수), 받는 쪽이 받은 글과 받은 연결 수, 연결 요청에서 결과가 나오기까지 걸린 시간입니다. 화면의 9000번은 예시이고 실제 실행에서는 조합마다 비어 있는 다른 번호를 골라 썼습니다(받는 쪽이 없는 조합은 방금 닫은 번호로 보냈고, TCP에서는 실제로 아무도 열지 않았다는 것이 연결 거부로 확인됩니다). 보내는 쪽은 A, B, C를 0.05초 간격으로 보냈습니다. TCP에서 연결이 실패하면 이 프로그램은 거기서 멈추고 보내는 줄을 실행하지 않게 짰습니다. 연결 거부 오류 코드 ECONNREFUSED와 UDP에서 오류가 없었다는 것은 이 PC(Windows 11)에서 관찰한 것이고 운영체제에 따라 다를 수 있습니다. 연결 요청의 결과(연결 성공이든 연결 거부든)는 이 PC에서 최대 2밀리초 안에 나왔고, 이 값은 같은 컴퓨터 안이라서 작은 것입니다. 보내는 쪽이 상대가 있는지 아는가는 같은 방식으로 받는 쪽이 있을 때와 없을 때 보내는 쪽이 본 것이 같은지 다른지로 정했습니다. TCP는 연결 성공과 연결 거부로 달랐고, UDP는 두 경우 모두 오류 없이 세 번 보내서 같았습니다. 다만 TCP에서 연결이 맺어졌다는 것이 보낸 글을 받는 쪽 프로그램이 읽었다는 확인까지 뜻하는지는 이 실습에서 다루지 않았고, 화면의 칸은 상대가 있는지만 말합니다. 받는 쪽이 받은 글 ABC는 두 프로토콜 모두 이 PC에서 보낸 차례대로였지만, 표준이 차례를 정해 주는 것은 TCP뿐입니다(UDP는 이 PC의 같은 컴퓨터 안 실행에서 관찰한 것이고 인터넷을 건너는 경우는 보지 않았습니다). TCP로 보낸 글을 받는 쪽이 몇 번에 나뉘어 읽는지는 다루지 않았습니다(이 실행에서는 세 번에 나뉘어 읽혔으나 문장에 쓰지 않았습니다). 따로 확인한 것으로, Node.js의 http 서버에 TCP로 연결해 HTTP 요청 글을 직접 쓰면 서버가 요청을 하나 받아 200 OK로 답했고, 같은 글을 UDP로 보내면 send는 오류 없이 끝났지만 서버는 요청을 받지 않았습니다. 운영체제가 연결을 거절할 때 실제로 거부 신호(RST)를 보냈는지와 UDP에서 받는 쪽이 없을 때 운영체제가 어떤 신호를 돌려보냈는지는 패킷을 잡아 보지 않아 확인하지 못했습니다. 문서로는 다음을 직접 열어 확인했습니다. RFC 9293(TCP)의 2.2절은 TCP가 연결을 맺는 방식이며 신뢰할 수 있고 순서가 지켜지는 바이트 스트림 서비스를 제공한다고, 3.5절은 연결을 맺는 절차가 3-way handshake라고, 3.5.2절은 연결이 없는 상태로 온 요청에 거부 신호(RST)를 보낸다고 적습니다(3.10절 이후는 열지 못했습니다). RFC 768(UDP)의 소개는 UDP에서 도착과 중복 방지가 보장되지 않는다고 적습니다. RFC 9112의 9절은 HTTP가 믿을 수 있는 순서 있는 전달을 전제로 하고 http 주소의 기본 연결이 TCP라고 적습니다. Node.js 문서 net은 연결에 문제가 있으면 connect 이벤트 대신 error 이벤트가 온다고 적지만 ECONNREFUSED라는 이름은 열어 본 부분에서 확인하지 못했고, dgram은 send의 콜백이 DNS 오류를 알리고 글을 담은 버퍼를 다시 써도 되는 때를 알려 준다고 적을 뿐 받는 쪽이 받았다는 확인이라고는 적지 않습니다. 이 실습은 TCP 연결 하나와 UDP 보내기만 다루며, 연결을 맺고 끊는 절차(3-way handshake, FIN), 글이 사라졌을 때의 재전송, 순서 맞추기, 흐름 제어와 혼잡 제어는 다루지 않았고 "세부 동작 실습: TCP 연결과 재전송"과 "세부 동작 실습: TCP와 UDP"에서 다룹니다. UDP 소켓에도 connect를 부르는 방법이 있지만 TCP처럼 연결을 맺는 것이 아니며 여기서는 쓰지 않았습니다.
줄을 그은 곳은 처음 코드에서 지운 것이고, 색을 칠한 곳은 새로 쓴 것입니다.