Network Programming · Part 1 — Fundamentals: How Data Actually Travels
The mental model every network programmer needs: the TCP/IP layers, IP addresses & ports, packets, and the client/server model — with a tiny Node.js + TypeScript demo, bilingual, plus exercises.
Đây là Phần 1 của series 10 bài về lập trình mạng với Node.js + TypeScript. Ta đi từ “port là gì” đến scale và debug server mạng thật.
Trước khi mở socket đầu tiên, bạn cần một mô hình tư duy vững: dữ liệu thực sự di chuyển thế nào giữa hai chương trình.
Mô hình phân tầng
Mạng được xây theo tầng — mỗi tầng chỉ nói chuyện với tầng trên và dưới nó. Là lập trình viên, bạn chủ yếu sống ở hai tầng trên cùng, nhưng nhìn cả stack sẽ rất có ích.
- Ứng dụng: giao thức code của bạn nói.
- Vận chuyển: TCP tin cậy hoặc UDP nhanh, cùng với port.
- Liên mạng: địa chỉ IP và định tuyến — đưa gói tin từ máy này sang máy khác.
- Liên kết: dây vật lý / Wi-Fi biến bit thành tín hiệu.
Ý chính: bạn ghi vào socket ở trên cùng; OS lo mọi tầng bên dưới.
Địa chỉ IP và port
Địa chỉ IP xác định một máy trên mạng; port xác định một chương trình cụ thể trên máy đó.
Hãy tưởng tượng một tòa chung cư: IP là địa chỉ đường, port là số căn hộ.
93.184.216.34 : 443
└──── IP ────┘ └ port ┘
the machine the program (here: HTTPS)
Một số port là quy ước: 80 = … Port 0–1023 là “well-known” và thường cần quyền; chọn số cao cho server của bạn.
Gói tin
Dữ liệu không được gửi thành một cục lớn. Nó bị cắt thành packet — các mảnh nhỏ đi độc lập, có thể đi đường khác nhau, đến sai thứ tự, hoặc thất lạc.
Sự thật này giải thích phần lớn của mạng:
- TCP ráp lại packet thành luồng có thứ tự, tin cậy giúp bạn.
- UDP đưa bạn bất cứ thứ gì đến — mất hay sai thứ tự là việc của bạn.
Ta sẽ xây cả hai ở Phần 2 và 3.
Mô hình client/server
Gần như mọi app mạng có hai vai:
- Server gắn vào một port và chờ kết nối.
- Client khởi tạo kết nối tới IP + port của server.
Chỉ vậy thôi — phần còn lại là chúng nói gì với nhau.
Nếm thử 12 dòng với Node.js
Bạn chưa cần hiểu từng dòng — chỉ cần cảm nhận hình dạng. Đây là server TCP chào bất kỳ ai kết nối:
import { createServer } from 'node:net';
// A server is just: bind a port, wait, react to each connection.
const server = createServer((socket) => {
console.log('client connected:', socket.remoteAddress);
socket.write('Hello from the server!\n');
socket.end();
});
server.listen(3000, () => {
console.log('listening on port 3000');
});
Chạy nó, rồi ở terminal khác kết nối bằng client thô:
node server.js # terminal 1
nc localhost 3000 # terminal 2 → prints "Hello from the server!"
nc (netcat) là bạn thân để chọc thử server. Ta sẽ dùng nó xuyên suốt series.
Lỗi người mới hay mắc
- Nhầm IP (máy) với port (chương trình).
- Tưởng TCP giữ ranh giới message — nó là luồng byte, không phải hàng đợi message.
- Bind server vào port đặc quyền rồi gặp “permission denied”.
- Tưởng
localhostvà IP LAN giống nhau —127.0.0.1chỉ là loopback.
Bài tập
Thử từng bài trước khi mở lời giải.
- Chạy server trên và kết nối bằng cả
ncvàtelnet. - Đổi port sang
80và giải thích lỗi nhận được. - Dùng
curl -vvà mô tả vì sao output trông lạ.
Lời giải
node server.js
nc localhost 3000 # → Hello from the server!
telnet localhost 3000 # same greeting, then connection closesBind port 80 không có quyền sẽ ném EACCES vì port dưới 1024 dành cho OS/root.
curl nói HTTP, nhưng server của ta trả lời bằng lời chào thường, không phải HTTP hợp lệ. curl in byte thô và phàn nàn response sai định dạng — màn dạo đầu hoàn hảo cho Phần 5.
Điều cốt lõi
Dữ liệu đi dạng packet qua các tầng; bạn định địa chỉ một chương trình bằng IP + port; server chờ, client kết nối. Có mô hình này, mở socket TCP thật ở Phần 2 sẽ thấy hiển nhiên.