Các thành phần cơ bản của mạng máy tính

Introduction

Việc giao tiếp giữa các máy tính hay thiết bị với nhau cần phải có một tập hợp các nguyên tắc, quy luật để đảm bảo vận hành trơn tru, đó là lý do protocols (hay giao thức).

Các ứng dụng hiện nay sử dụng phổ biến mô hình client-server. Ở đây là định nghĩa lấy từ sách nên có hơi chút cô đọng, thực ra bản thân server không chỉ gửi các message mà thực ra nó cung cấp tài nguyên, ở đây có thể là file ảnh, video, hoặc cung cấp service cho các ứng dụng khác.

TCP/IP Protocol Suite

Khi chúng ta khi nhắc đến TCP/IP thường hiểu nhầm nó là một giao thức đơn lẻ, nhưng thực ra lại là bộ các giao thức kết hợp cùng nhau để khiến internet hoạt động. Bản thân bộ giao thức này được chia theo các layers, trong đó nếu client muốn trao đổi dữ liệu cho server thì không phải gửi trực tiếp, mà phải đi qua TCPIPEthernet rồi ngược lên lại đến server.

Chính vì vậy, Client/Server là các user process, được chạy ở môi trường của user. TCP/IP và các giao thức ở mức độ thấp hơn sẽ do kernel quản lý và thực thi.

Mô hình OSI

Ngoài kia có rất rất nhiều giao thức khác nhau cần một cơ chế để có thể chuẩn hóa và biểu diễn, mô tả các giao thức này. Từ đó sinh ra mô hình OSI, một quy chuẩn để biểu diễn các giao thức, bao gồm 7 layers.

  • Application: Liên quan đến các ứng dụng mà chúng ta dùng hằng ngày (mail, zalo, …).
  • Presentation: Biểu diễn dữ liệu và mã hóa.
  • Session: Quản lý các phiên giao tiếp.
  • Transport: Liên quan đến các cơ chế bảo toàn dữ liệu, phân tách và một số cơ chế hỗ trợ truyền tải.
  • Network: Routing và xử lý địa chỉ.
  • Datalink và physical
Mapping mô hình OSI với tập giao thức TCP/IP

Đầu tiên, tập TCP/IP gom 3 lớp trên cùng thành 1 lớp application duy nhất. Transport layer chúng ta có các giao thức như TCP/UDP, network layer chúng ta có IPv4, IPv6, và datalink cùng physical layer cũng gom thành 1 lớp abstraction luôn.

Elementary Sockets

Vai trò của Sockets

Socket có thể được mô tả theo 2 hướng:

  • Nó là điểm bắt đầu và kết thúc của quá trình giao tiếp trong mạng máy tính. Lấy ví dụ như hình 6, Host không giao tiếp trực tiếp với Server, mà phải thông qua Socket.
  • Cụ thể hơn, Socket chính là API, phần interface nằm giữa Application layer và Transport layer, giúp cho 2 layer này có thể giao tiếp với nhau. Cách thiết kế này cũng góp phần phân định rõ ra ở bên trên là user space, chú tâm vào cách ứng dụng hoạt động. Ở bên dưới là kernel space, tập trung vào quá trình giao tiếp.
Socket address structure(IPv4)

Đây là struct dùng để lưu giá trị địa chỉ IP cũng như Port number, sau đó truyền từ process xuống kernel hoặc ngược lại.

  • sin_len sẽ không được sử dụng tới vì biến này chỉ sử dụng trong các hệ thống BSD.
  • sin_zero cũng không được sử dụng tới, nhưng cần thiết để fill vào chỗ trống vì khi ép kiểu sang generic structure, độ lớn của struct này sẽ bị bé hơn.
Socket address structure (IPv6)

Đây là struct dành cho IPv6. Cấu trúc tương tự như IPv4 nhưng có một số lưu ý như sau:

  • Trường địa chỉ giờ có độ lớn là 128 bit.
  • Có thêm 2 trường mới là flowinfo và scope_id tương ứng với các tính năng nâng cao hơn của IPv6, chúng ta sẽ không bàn tới ở đây.
Generic Socket Structure

Chúng ta có IPv4 và IPv6, cùng với các họ giao thức khác. Bản thân C không có polymophism như C++ (như template, giúp mình có thể tái định nghĩa hoặc sử dụng một tên hàm hoặc tên biến với nhiều kiểu dữ liệu khác nhau), chúng ta cần cơ chế khác để có thể truyền address structure vào Generic Address Structure. Một address structure rút gọn để các address structure khác đều có thể ép kiểu sang trước khi truyền vào hàm.

Byte Ordering Functions

Phần này nói về lý thuyết liên quan đến Big-endian và Little-endian. Về cơ bản thì đây là cách tổ chức dữ liệu trong bộ nhớ, với Big-endian là bit có trọng số lớn nhất được xếp trước, và ngược lại với Little-endian. Vấn đề đặt ra là phần lớn các máy tính hiện nay sử dụng kiến trúc x86_64, kiến trúc này sử dụng little-endian. Vì vậy trước khi được sử dụng, các địa chỉ cũng như port trước khi sử dụng cần phải chuyển về dạng Big Endian, vì đây là quy chuẩn của các hệ thống mạng.

Các hàm chuyển đổi địa chỉ

Chúng ta có các hàm để chuyển địa chỉ ở dạng chuỗi, format là dot notation sang dạng binary để kernel xử lý. Đối với ác hàm pton và nop, chúng ta sử dụng void pointer để hàm có thể nhận pointer đến mọi kiểu dữ liệu, bao gồm cả IPv6.

Stream I/O

Các hàm readn, writen được lấy từ trong sách, đây là những hàm được sinh ra để giải quyết vấn đề của hàm truyền thống như read và write. Đối với TCP khi truyền còn có quá trình fragmentation (phân đoạn packet), nên nếu truyền 100 bytes, chúng ta không biết được sẽ truyền 100 byte một lúc hay 2 lần 50 bytes, hay 5 lần 20 bytes, sử dụng thêm một giá trị nbytes để đảm bảo việc truyền nhận được trọn vẹn. Tuy nhiên, thực tế chúng ta cũng không rõ số byte nhận được là bao nhiêu, trong sách cũng ít sử dụng các hàm readn và writen này mà họ thường sử dụng các cơ chế như check giá trị null nhiều hơn.