- Vào còng lặp while: server tiếp tục lắng nghe các gói tin từ client và phản hồi lại.- Nhận dữ liệu từ client: sử dụng phương thức recvfrom trên server_socket để nhận dữ liệu từ client.
Trang 1ĐẠI HỌC QUỐC GIA TP HỒ CHÍ MINH
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
KHOA CÔNG NGHỆ PHẦN MỀM
<NHẬP MÔN MẠNG MÁY TÍNH>
LỚP: IT005.P116
BÁO CÁO BÀI TẬP 4
NHÓM 11: NGÔI NHÀ TÌNH THƯƠNG
YÊU TỔ QUỐC YÊU ĐỒNG BÀO
GIẢNG VIÊN: ThS TRẦN MẠNH HÙNG
Trang 2MỤC LỤC
I PHÂN CHIA CÔNG VIỆC
II TRẢ LỜI CÂU HỎI
1 Vẽ bảng chú giải (STT, Query/Answer) của truy vấn đệ quy DNS trong slide 72.
2 Xây dựng chương trình: Chat console theo mô hình client – server dùng python, dùng TCP và UDP.
3 Bảng Hash dùng để làm gì
4 Checksum dùng để làm gì, cho ví dụ tính checksum 16 bits
5 Phân biệt Multiplexing với Demultiplexing trong Internet
6 Vì sao phải dùng các nguyên lý truyền tin tin cậy, so sánh sự khác nhau của các nguyên lý rdt 1.0, rdt2.0, rdt 2.1, 2.2 và rdt 3.0.
7 Vẽ lại mô hình FSM của rdt 3.0 bên nhận
8 Bài tập trong sách chương 3: R4, R6, R7, P1, P4.
III NHẬN XÉT
Trang 3I DANH SÁCH THÀNH VIÊN
Trang 4II TRẢ LỜI CÂU HỎI
Câu 1: Vẽ bảng chú giải (STT, Query/Answer) của truy vấn đệ quy DNS trong slid 72.
Bảng chú giải (STT, Query/Answer) của truy vấn đệ quy DNS
1 Q: who is gaia.cs.umass.edu?
2 Q: who is gaia.cs.umass.edu?
3 Q: who is gaia.cs.umass.edu?
4 Q: who is gaia.cs.umass.edu?
5 A: 128.119.245.12
6 A: 128.119.245.12
7 A: 128.119.245.12
8 A: 128.119.245.12
Sơ đồ phân giải tên DNS: truy vấn đệ quy
Trang 5Câu 2: Xây dựng chương trình: Chat console theo mô hình client – server dùng python, dùng TCP và UDP
a Dùng TCP
Tạo 2 file python là TCP_Server.py và TCP_Client.py với mã như sau:
TCP_Sever.py
Trang 6Giải thích:
- import socket: là một lệnh để nhập thư viện socket sử dụng để làm việc với mạng và giao thức TCP/IP
- Hàm main(): là hàm chính của chương trình, nơi mọi thứ bắt đầu
- host và port: biến host xác định máy chủ sẽ lắng nghe trên địa chỉ IP localhost, có nghĩa
là máy chủ sẽ lắng nghe các kết nối trên máy tính hiện tại Biến port xác định cổng (port)
mà máy chủ sẽ lắng nghe trên
- server_socket = socket.socket(socket AF_INET, socket SOCK_STREAM): ở đây, chúng ta tạo một đối tượng socket sử dụng giao thức AF_INET (IPV4) và SOCK_STREAM (TCP)
- server_socket.listen(): chúng ta cho phép máy chủ lắng nghe các kết nối đếm Điều này tạo ra một máy chủ lắng nghe trên địa chỉ host và cổng port
- connection, address = server_socket.accept(): khi có một kết nối đến máy chủ, nó
sẽ chấp nhận kết nối và trả về một đối tượng kết nối (connection) và địa chỉ của máy khách (address)
- Trong vòng lặp vô hạn while True, máy chủ nhận dữ liệu từ máy khách bằng cách sử dụng connection.recv (1024) Dữ liệu nhận được sau đó được giải mã từ dạng bytes thành chuỗi bằng .decode() Nếu không có dữ liệu (hoặc kết nối bị đóng), vòng lặp sẽ thoát
- Sau đó, máy chủ in ra thông điệp nhận được từ máy khách và gửi lại một phản hồi lại máy khách bằng cách sử dụng connection.send(reply.endode())
- Cuối cùng, khi kết thúc vòng lặp, máy chủ đóng kết nối bằng connection.close()
- Cuối cùng, trong if_name_== ‘_main_’:, hàm main() được gọi khi chương trình chạy
Trang 7TPC_Client.py
Giải thích:
- import socket: Đây là lệnh để nhập thư viện socket, cần thiết để làm việc với mạng và giao thức TCP/IP
- def main(): hàm chính của chương trình bắt đầu ở đây
- host và port: địa chỉ IP của máy chủ và cổng mà máy khách sẽ kết nối đến
- Tạo đối tượng socket sử dụng giao thức IPV4 (AF_INET) và TCP (SOCKET_STREAM)
- Kết nối đến máy chủ sử dụng địa chỉ và cổng đã xác định
- Bắt đầu một vòng lặp vô hạn để cho phép người dùng nhập dữ liệu và gửi nó đến máy chủ
- Người dùng được yêu cầu nhập dữ liệu thông qua input(), và dữ liệu được lưu trong biến message
- Dữ liệu nhập từ người dùng sau đó được gửi đến máy chủ sau khi được mã hóa thành dạng bytes bằng client_socket.send(message.encode())
- Máy khách nhận phản hồi từ máy chủ bằng cách sử dụng client_socket.recv(1024), sau
đó giải mã dữ liệu thành chuỗi bằng .decode()
- Phản hồi từ máy chủ sau đó được in ra màn hình
- Máy khách tiếp tụ vòng lặp để cho phép người dùng nhập và gửi thêm dữ liệu nếu cần
- Khi vòng lặp kết thúc, máy khách đóng kết nối bằng client_socket.close()
- Cuối cùng, mẫ kiểm tra xem chương trình có được chạy như một chương trình chính không, và nếu có, nó gọi hàm main()
Hình minh họa code khi chạy:
Trang 8Khi run file TCP_Server.py:
Khi run file TCP_Client.py:
Server nhận dữ liệu từ client:
Trang 9b Dùng UDP
Tạo 2 file python là UDP_Server.py và UDP_Client.py với mã như sau:
UDP_Server.py
Giải thích:
- Import socket: thư viện này cung cấp các hàm và lớp để thực hiện giao tiếp mạng
- Xây dựng hàm main(): trong hàm main, xây dựng các hoạt động chính của server
- Khởi tạo biến host và port: biến host lưu trữ địa chỉ IP của server (ở đây là ‘localhost’) Biến port lưu trữ số của cổng kết nối mà server sẽ lắng nghe
- Tạo socket UDP: sử dụng hàm socket.socket(socket.AF_INET, socket.SOCK_DGRAM) để tạo một socket UDP
- Gán địa chỉ IP và cổng cho socket: sử dụng phương thức bind() để gắn kết địa chỉ IP và cổng với socket đã tạo Địa chỉ IP và cổng được lấy từ biến host và port
- In thông báo “Server is ready”: thông bày cho biết rằng server đã khởi động và đang lắng nghe kết nối từ client
Trang 10- Vào còng lặp while: server tiếp tục lắng nghe các gói tin từ client và phản hồi lại.
- Nhận dữ liệu từ client: sử dụng phương thức recvfrom() trên server_socket để nhận dữ liệu từ client Đối số 1024 cho biết kích thước tối đa của dữ liệu nhận được Dữ liệu nhận được lưu trong biến data, và địa chỉ của client lưu trong biến addr
- In thông tin về dữ liệu nhận được: in địa chỉ IP của client (lấy từ addr[0]) và nội dung dữ liệu nhận được (giải mã từ dạng bytes sang chuỗi ký tự bằng phương thức decode())
- Gửi dữ liệu đến client: Tạo một phản hồi bằng cách ghép chuỗi “Message receive:” với dữ liệu nhận được, và sau đó mã hóa phản hồi thành dạng bytes bằng phương thứ encode() Sử dụng phương thức sendto() để gửi phản hồi tới địa chỉ của client (addr) thông qua server_socket
- if_name_==’_main’: đảm bảo rằng đoạn mã bên trong chỉ được thực thi khi chương
trình được chạy trực tiếp, không phải khi nó được import như một module
UDP_Client.py
Trang 11Giải thích:
- import socket: thư viện này cung cấp các hàm và lớp để thực hiện giao tiếp mạng
- Xây dựng hàm main(): trong hàm main, xây dựng các hoạt động chính của client
- Khởi tạo biến host và port: biến host lưu trữ địa chỉ IP của server (ở đây là ‘localhost’) Biến port lưu trữ số của cổng kết nối mà client sẽ sử dụng để kết nối tới server
- Tạo socket UDP: sử dụng hàm socket.socket(socket.AF_INET, socket.SOCK_DGRAM) để tạo một socket UDP
- Vào vòng lặp while: client tiếp tực lặp lại các bước dưới đây để gửi và nhận tin nhắn với server
- Nhập tin nhắn của người dùng: sử dụng hàm input() để nhận tin nhắn từ người dùng và lưu nó vào biến message
- Gửi tin nhắn đến server: sử dụng phương thức recvfrom() trên client_socket để nhận
dữ liệu từ server Số 1024 cho biết kích thước tối đa của dữ liệu nhận được Dữ liệu nhận được lưu trong biến data, và địa chỉ của server lưu trong biến addr
- In phản hồi từ server: hiển thị nội dung dữ liệu nhận được từ server bằng cách giải mã dữ liệu từ dạng bytes sang chuỗi ký tự bằng phương thức decode()
- if_name_==’_main_’: đảm bảo rằng đoạn mã bên trong chỉ được thực thi khi chương trình được chạy trực tiếp, không phải khi nó được import như một module
Hình minh họa code khi chạy:
Khi run file UDP_Server.py:
Khi run file UDP_Client.py:
Server nhận dữ liệu từ client:
Trang 12Câu 3: Bảng Hash dùng để làm gì
Định nghĩa: Bảng Hash (hash table) là một cấu trúc dữ liệu được sử dụng để lưu trữ các cặp
khóa-giá trị (key-value pair), cho phép truy cập dữ liệu một cách hiệu quả Mục đích chính của bảng hash là hỗ trợ tìm kiếm, chèn và xóa phần tử nhanh chóng
Ứng dụng:
- Tìm kiếm nhanh: Hash table cho phép truy cập đến một phần tử dựa trên khóa của nó mà không cần phải duyệt qua toàn bộ danh sách
- Lưu trữ dữ liệu động: Dữ liệu có thể được thêm hoặc xóa dễ dàng trong bảng hash
- Giải quyết các vấn đề liên quan đến ánh xạ: Như ánh xạ các từ vào tần suất xuất hiện trong phân tích văn bản
- Triển khai bộ nhớ đệm (cache): Giúp tăng hiệu suất bằng cách lưu trữ kết quả các phép tính tốn kém
- Phát hiện phần tử trùng lặp: Dễ dàng kiểm tra xem một phần tử có tồn tại hay chưa
Câu 4: Checksum dùng để làm gì, cho ví dụ tính checksum 16 bits
Định nghĩa: Checksum là một kỹ thuật dùng để kiểm tra tính toàn vẹn của dữ liệu khi truyền
hoặc lưu trữ
Mục đích: Phát hiện lỗi xảy ra trong quá trình truyền dữ liệu hoặc lưu trữ do các nguyên nhân
như nhiễu tín hiệu hoặc hư hỏng phần cứng
Ví dụ: Giả sử ta có một chuỗi dữ liệu là 4 byte (32 bit): 0x1234 và 0xABCD.
- Chia dữ liệu thành 2 khối 16-bit : 0x1234 và 0xABCD, cộng 2 khối lại với nhau
0x1234
+ 0xABCD
0xBE01
- Tính giá trị checksum bằng cách lấy số bù của 0xBE01
Checksum = ~0xBE01 = 0x41FE
Trang 13Câu 5: Phân biệt Multiplexing với Demultiplexing trong Internet
Định nghĩa:
- Multiplexing (Ghép kênh): Là quá trình kết hợp nhiều luồng dữ liệu từ các ứng dụng
hoặc nguồn khác nhau thành một luồng duy nhất để truyền qua một kênh mạng chung
- Demultiplexing (Tách kênh): Là quá trình ngược lại của multiplexing, tách một luồng
dữ liệu đã nhận thành các luồng riêng biệt dựa trên thông tin định danh (số cổng hoặc địa chỉ)
Phân Biệt:
Nơi thực hiện Máy gửi (Sender)
Mục đích
Tận dụng băng thông mạng hiệu quả bằng cách truyền nhiều luồng
dữ liệu qua một kênh chung
Phân phối các gói dữ liệu tới đúng ứng dụng hoặc tiến trình đang yêu cầu
Hoạt động
Nhiều luồng dữ liệu từ các ứng dụng khác nhau được gán số cổng (port number) và ghép lại để truyền qua một đường truyền duy nhất
Dựa trên số cổng (port number), luồng dữ liệu được tách ra và chuyển đến đúng ứng dụng hoặc tiến trình
Liên quan
giao thức
Giao thức TCP hoặc UDP sẽ gán số cổng để phân biệt các luồng dữ liệu khác nhau trước khi ghép kênh
Dựa trên số cổng từ gói tin để xác định đúng ứng dụng hoặc quá trình nhận dữ liệu
Tầng OSI liên
quan
Tầng Vận chuyển (Transport Layer
- TCP/UDP)
Tầng Vận chuyển (Transport Layer
- TCP/UDP)
Ví dụ
Dữ liệu từ trình duyệt web (HTTP), email (SMTP), và truyền file (FTP) được ghép lại để truyền qua một kết nối mạng
Máy nhận nhận gói dữ liệu từ trình duyệt web và email, tách dữ liệu dựa trên số cổng và chuyển đến đúng ứng dụng
Trang 14Câu 6: Vì sao phải dùng các nguyên lý truyền tin tin cậy, so sánh sự khác nhau của các nguyên lý rdt 1.0, rdt2.0, rdt 2.1, 2.2 và rdt 3.0.
Lý do phải dùng nguyên lý truyền tịn tin cậy: Để đảm bào dữ liệu được truyền tử nguồn tới
dích một cách chính xác, không bị lắn lộn hoặc bị sửa đổ trong quá trình truyền
So sánh:
RDT 1.0
Kênh truyền tin tin cây hoàn toàn - Sử dụng dừng và chở để đảm bảo truyền tin cây - Không có xử lý tình huống mất dữ liệu hoặc dữ liệu không theo thứ tự - Đơn giản không đòi hỗi nhiều tài nguyên tỉnh
toán
RDT 2.0
Vẫn đề kênh truyền có lỗi → Giải quyết : ACK và NAK - Sử dụng checksum để kiểm tra lỗi: • Nếu không có lối, bên nhận gửi ACK báo
đã nhận được gói tin • Nếu có lỗi, bên nhận gửi NAK báo rằng gói tin
bị lỗi và bên nhận gửi lại gỏi tin - Tốt hơn RDT 1.0 khi có cách giải
quyết bằng ACK và NAK khi kênh truyền lổi
RDT 2.1
Vấn để ACK/NAK bị lối - Sử dụng ACK/NAK cho việc truyền một dấy gói tin liên tiếp có thể gây ra trùng lắp - Giải quyết bằng cách đánh dầu gói tin, ACK và NAK để đảm bảo truyền đủ gói tin và không bị trùng láp - Tốt hơn RDT 2.0 vỉ giải quyết được lỗ hổng của
ACK/NAK RDT 2.2
Tương tự như giao thức 2.1 nhưng không cần NAK - Ở một sổ trường hợp việc gửi NAK không có ý nghĩa lắm nên có thể bỏ - Tốt hơn RDTT2.1 vì giảm bót được việc phải gửi NAK giúp tiết kiệm được
thời gian
RDT 3
Vẫn đề mất gói tin → Giải quyết bằng cách thêm timer vào Khi timer bảo hết thời gian thì có nghĩa đã xày ra mất gói tin, và gói tin sẽ được gửi lại - Tốn nhiều thời gian hơn nhưng đảm bảo dữ liệu chắc chắn được truyền đủ và không có เเเi - Có thể tang hiệu suất bằng các
gửi theo kiểu Pipelining
Trang 15Câu 7: Vẽ lại mô hình FSM của rdt 3.0 bên nhận.
Câu 8: Bài tập trong sách chương 3: R4, R6, R7, P1, P4.
R4: Describe why an application developer might choose to run an application over UDP rather than TCP (Mô tả lý do tại sao nhà phát triển ứng dụng có lẽ nên chọn chạy ứng dụng qua UDP thay vì TCP.)
Khái niệm UDP: UDP (User Datagram Protocol) là giao thức không kết nối, truyền dữ liệu
nhanh nhưng không đảm bảo tính toàn vẹn và thứ tự gói tin Thường dùng trong các ứng dụng yêu cầu tốc độ cao như streaming, game online
Khái niệm TCP: TCP (Transmission Control Protocol) là giao thức có kết nối, đảm bảo dữ
liệu được truyền đúng thứ tự và toàn vẹn Phù hợp cho các ứng dụng như email, duyệt web, và truyền tải file
Một nhà phát triển ứng dụng có thể chọn sử dụng UDP thay vì TCP vì các lý do sau:
1 Tốc độ và hiệu năng: UDP là giao thức không kết nối và không yêu cầu thiết lập phiên
kết nối giữa các thiết bị trước khi gửi dữ liệu Điều này làm giảm độ trễ và tăng tốc độ truyền dữ liệu, rất phù hợp với các ứng dụng yêu cầu tốc độ cao như truyền phát video trực tiếp (live streaming), trò chơi trực tuyến (online gaming), hay các ứng dụng thời gian thực
Trang 162 Không cần đảm bảo tính toàn vẹn dữ liệu: Trong một số ứng dụng, việc đảm bảo toàn
vẹn dữ liệu (như với TCP) không quá quan trọng, ví dụ như trong truyền phát âm thanh hoặc video, nơi mà một vài gói dữ liệu bị mất hoặc đến trễ sẽ không ảnh hưởng nghiêm trọng đến trải nghiệm người dùng UDP không thực hiện việc kiểm tra và khôi phục dữ liệu bị mất, giúp tối ưu hóa hiệu năng
3 Không có cơ chế kiểm soát luồng và tắc nghẽn: Với TCP, có các cơ chế kiểm soát
luồng (flow control) và tắc nghẽn (congestion control) để điều chỉnh lượng dữ liệu truyền tải dựa trên điều kiện mạng Tuy nhiên, trong một số trường hợp, điều này có thể làm giảm hiệu năng khi cần truyền dữ liệu nhanh UDP không có những cơ chế này, cho phép
dữ liệu được truyền tải liên tục mà không bị kiểm soát
4 Đơn giản hơn: UDP là một giao thức đơn giản hơn, ít phức tạp hơn so với TCP Điều
này có thể giảm chi phí về mặt tài nguyên hệ thống khi triển khai các ứng dụng cần xử lý lượng lớn dữ liệu trong thời gian ngắn
Tóm lại, các nhà phát triển chọn UDP khi họ cần tốc độ nhanh, độ trễ thấp và không yêu cầu
việc đảm bảo dữ liệu đến đích một cách chính xác như TCP
R6: Is it possible for an application to enjoy reliable data transfer even when the application runs over UDP? If so, how? (Một ứng dụng có thể đảm bảo truyền dữ liệu tin cậy ngay cả khi ứng dụng chạy trên giao thức UDP không? Nếu có, làm bằng cách nào?)
Mặc dù giao thức UDP không cung cấp cơ chế truyền dữ liệu tin cậy như TCP, nhưng một ứng dụng vẫn có thể đạt được việc truyền dữ liệu tin cậy ngay cả khi chạy trên UDP Điều này có thể đạt được bằng cách tự triển khai các cơ chế đảm bảo truyền dữ liệu trong ứng dụng Cụ thể:
1 Tái tạo cơ chế xác nhận và gửi lại (ACK & Retransmission):
o Ứng dụng có thể tự xác định khi nào một gói tin bị mất bằng cách chờ xác nhận (ACK) từ phía nhận Nếu không nhận được ACK sau một khoảng thời gian, ứng dụng có thể gửi lại gói tin đó
2 Đánh số thứ tự cho các gói tin:
o Ứng dụng có thể thêm số thứ tự vào các gói tin để đảm bảo rằng các gói tin được nhận theo đúng thứ tự Phía nhận có thể sử dụng số thứ tự để tái tạo lại luồng dữ liệu ban đầu
3 Phát hiện và sửa lỗi:
o Ứng dụng có thể bổ sung thông tin kiểm tra lỗi (checksum) vào các gói tin để phát hiện xem gói tin có bị lỗi trong quá trình truyền hay không Nếu phát hiện lỗi, ứng dụng có thể yêu cầu gửi lại gói tin