Từ bài 1 đến giờ mình đã hướng dẫn và thực hành việc truyền nhận dữ liệu qua TCP rất nhiều, bây giờ chúng ta sẽ tìm hiểu kĩ hơn về TCP và UDP !
TCP
Tham khảo: https://vi.wikipedia.org/wiki/TCP
Giao thức TCP là gì?
Nó là giao thức điều khiển truyền vận (Transmission Control Protocol) thuộc giao thức cốt lõi của bộ giao thức TCP/IP. Thông qua TCP, các ứng dụng trên các máy chủ được nối mạng có thể liên lạc với nhau, qua đó chúng có thể trao đổi giữ liệu hoặc các gói tin. Giao thức này đảm bảo chuyển giao dữ liệu tới nhận một cách đáng tin cậy và đúng thứ tự. Hơn nữa, TCP có chức năng phân biệt giữa dữ liệu của nhiều ứng dụng (như dịch vụ Web và dịch vụ Email) đồng thời chạy trên cùng một máy chủ.
- TCP là giao thức hướng kết nối (connection-oriented), có nghĩa là buộc phải thiết lập kết nối trước sau đó mới đến tiến trình truyền dữ liệu.
- Cung cấp cơ chế đánh số thứ tự gói tin (sequencing): sử dụng để ráp các gói tin chính xác ở điểm nhận, loại bỏ gói tin trùng lặp.
- TCP có khả năng truyền và nhận dữ liệu cùng một lúc — song công (full-duplex).
- Cơ chế báo nhận (Acknowledgement): tức là khi A gửi gói tin cho B, nếu B nhận được thì sẽ gửi thông báo cho A, trường hợp A không nhận được thông báo thì sẽ gửi lại gói tin tới khi nào B báo nhận thì thôi.
- Tính năng phục hồi dữ liệu bị mất trên đường truyền.
Đặc điểm
Một số đặc điểm cơ bản của TCP để phân biệt với UDP:
- Truyền dữ liệu không lỗi (do có cơ chế sửa lỗi/truyền lại)
- Truyền các gói dữ liệu theo đúng thứ tự
- Truyền lại các gói dữ liệu mất trên đường truyền
- Loại bỏ các gói dữ liệu trùng lặp
- Cơ chế hạn chế tắc nghẽn đường truyền
Cấu trúc gói tin
Một gói tin TCP bao gồm 2 phần
- header (có độ dài 20 bytes)
- dữ liệu
Phần header có 11 trường trong đó 10 trường bắt buộc. Trường thứ 11 là tùy chọn (trong bảng minh họa có màu nền đỏ) có tên là: options
Source port : Số hiệu của cổng tại máy tính gửi.
Destination port : Số hiệu của cổng tại máy tính nhận
Sequence number : Trường này có 2 nhiệm vụ. Nếu cờ SYN bật thì nó là số thứ tự gói ban đầu và byte đầu tiên được gửi có số thứ tự này cộng thêm 1. Nếu không có cờ SYN thì đây là số thứ tự của byte đầu tiên.
Acknowledgement number : Nếu cờ ACK bật thì giá trị của trường chính là số thứ tự gói tin tiếp theo mà bên nhận cần
Data offset : Trường có độ dài 4 bít quy định độ dài của phần header (tính theo đơn vị từ 32 bít). Phần header có độ dài tối thiểu là 5 từ (160 bit) và tối đa là 15 từ (480 bít) Reserved : Dành cho tương lai và có giá trị là 0
Flags (hay Control bits) : Bao gồm 6 cờ: URG ACK PSH RST SYN FIN
Window : Số byte có thể nhận bắt đầu từ giá trị của trường báo nhận (ACK)
Checksum : 16 bít kiểm tra cho cả phần header và dữ liệu. Phương pháp sử dụng được mô tả trong RFC 793:
Urgent pointer : Nếu cờ URG bật thì giá trị trường này chính là số từ 16 bít mà số thứ tự gói tin (sequence number) cần dịch trái.
Options : Đây là trường tùy chọn. Nếu có thì độ dài là bội số của 32 bít.
Hết phần Header là Dữ liệu
Thực ra nếu các bạn chỉ làm việc với esp8266 thôi thì cũng không cần quan tâm quá sâu vào cấu trúc Header của giao thức TCP đâu, vì thư viện wifi hay tập lệnh AT đã lo phần này cho chúng ta rồi. Nhưng do sau này mình sẽ hướng dẫn các bạn làm việc với mạng ethernet nữa ( module ENC28J60) nên mình nói rõ ở bài này luôn. ( khi làm việc với module ethernet ENC28J60 chúng ta sẽ tự thân vận động viết thư viện giao tiếp để hiểu cho rõ )
UDP
Tham khảo: https://vi.wikipedia.org/wiki/UDP
UDP (User Datagram Protocol) là một trong những giao thức cốt lõi của giao thức TCP/IP. Dùng UDP, chương trình trên mạng máy tính có thể gửi những dữ liệu ngắn được gọi là datagram tới máy khác. UDP không cung cấp sự tin cậy và thứ tự truyền nhận mà TCP làm; các gói dữ liệu có thể đến không đúng thứ tự hoặc bị mất mà không có thông báo. Tuy nhiên UDP nhanh và hiệu quả hơn đối với các mục tiêu như kích thước nhỏ và yêu cầu khắt khe về thời gian. Do bản chất không trạng thái của nó nên nó hữu dụng đối với việc trả lời các truy vấn nhỏ với số lượng lớn người yêu cầu
Cấu trúc gói tin
UDP không đảm bảo cho các tầng phía trên thông điệp đã được gửi đi và người gửi cũng không có trạng thái thông điệp UDP một khi đã được gửi
Phần header của UDP chỉ chứa 4 trường dữ liệu, trong đó có 2 trường là tùy chọn (ô nền đỏ trong bảng)
Source port : Trường này xác định cổng của người gửi thông tin và có ý nghĩa nếu muốn nhận thông tin phản hồi từ người nhận. Nếu không dùng đến thì đặt nó bằng 0
Destination port : Trường xác định cổng nhận thông tin, và trường này là cần thiết.
Length : Trường có độ dài 16 bit xác định chiều dài của toàn bộ datagram: phần header và dữ liệu. Chiều dài tối thiểu là 8 byte khi gói tin không có dữ liệu, chỉ có header.
Checksum : Trường checksum 16 bit dùng cho việc kiểm tra lỗi của phần header và dữ liệu. Phương pháp tính checksum được định nghĩa trong RFC 768.
Do thiếu tính tin cậy, các ứng dụng UDP nói chung phải chấp nhận mất mát, lỗi hoặc trùng dữ liệu.
Thực hành truyền nhận dữ liệu qua UDP với ESP8266
Do chúng ta đã làm việc với TCP nhiều nên phần này mình chỉ demo với UDP
Các lệnh AT thường dùng cho UDP
Tham khảo : https://www.espressif.com/sites/default/files/4b-esp8266_at_command_examples_en_v1.3.pdf
AT+CIPSTART=”UDP”,”192.168.1.14″,8000,23,0$0D$0A
Trong đó:
- UDP là tên giao thức ta muốn xài
- 192.168.1.14 là địa chỉ ip của đối phương
- 8000 là cổng dùng để nhận data của đối phương
- 23 là cổng dùng để nhận data của esp8266
- 0 thì các bạn để mặc định ( hoặc tìm hiểu thêm trong file pdf tham khảo phái trên)
AT+CIPSEND=X$0D$0A
Lệnh này để gửi 1 lượng dữ liệu có độ dài là X đến IP đã kết nối ở phía trên. Sau lệnh này esp8266 trả về “>” và chúng ta gửi dữ liệu đi với đúng độ dài X là được
Test
Mình sẽ truyền nhận thủ công bằng phần mềm Hercules. Các bạn mở 2 app Herculess lên, 1 app để giao tiếp Serial với eso8266, 1 app mở mục UDP
Ở app mở tab UDP, mình điền:
Module IP chính là ip của esp8266 ( dùng lệnh AT+CIFSR để lấy IP của esp8266)
Port là cổng nhận dữ liệu của esp8266 (23)
Listen là cổng nhận dữ liệu của máy tính (8000)
Sau đó ấn Listen để khởi tạo kết nối UDP cho máy tính
Với ESP8266
Bước 1 : khởi tạo kết nối UDP với máy tính bằng lệnh
AT+CIPSTART=”UDP”,”192.168.1.14″,8000,23,0$0D$0A
Với 192.168.1.14 là IP của máy tính (nếu không biết thì vào cmd -> gõ ipconfig để lấy ip của máy tính
Bước 2: Đo xem chuỗi data gửi đi dài bao nhiêu, ví dụ mình gửi nội dung là ESP8266_hello_PC thì chuỗi này dài 16
Bước 3: Gửi AT+CIPSEND=16$0D$0A
Bước 4: Gửi ESP8266_hello_PC
Trăm nghe không bằng 1 thấy, đưới dây là video test
Xem thêm:
[IoT] Bài 8: Giao thức MQTT với tập lệnh ATcommand – esp8266
[IoT] Bài 7: ESP8266 – arduino ide và giao thức MQTT
[IoT] Bài 5: Tạo WebServer với ESP8266 và lập trình cho esp8266 bằng arduino IDE
[IoT] Bài 3: ESP8266 Demo ứng dụng điều khiển LED từ xa qua internet bằng tập lệnh AT
[IoT] Bài 2: Giao tiếp với module WiFi ESP8266 bằng tập lệnh AT
A ơi. E có thể hói a cái này