[ENC28J60] Bài 12: Giao thức TCP – thiết lập kết nối

giao thuc tcp

Bạn nào chưa tìm hiểu về lí thuyết của giao thức TCP thì xem lại bài trước nhé !

Hãy chắc chắn vững vàng lí thuyết ở bài trước thì bài này mới hiểu vì mình không nhắc lại mà đi vào code luôn 🙂

Khởi tạo thư viện tcp

Tiếp tục tạo 2 file tcp.htcp.c và copy nội dung khởi tạo và add file thư viện vào project

Nội dung khởi tạo cho file tcp.h

Nội dung khởi tạo cho file tcp.c

Các bạn add thư viện tcp.h vào thư viện net.h và tiến hành kiểm tra gói IP có protocol = 0x06 ở hàm NET_ipRead để ném gói cho thư viện tcp xử lí

Vậy là xong quá trình khởi tạo mà chắc các bạn đã quá quen thuộc. Từ giờ là công việc của thư viện tcp

Thiết lập kết nối cho giao thức TCP

Chúng ta sẽ bắt xem đã nhận được gói tcp nào chưa nhé. Trong file hàm TCP_read mình thêm dòng debug

Chạy mô phỏng, mở WireShark, chọn chế độ lọc IP để tránh show các gói không cần thiết, và mở phần mềm Hercules, tab TCP Client, điền IP của ENC28j60 là 192.168.1.197 và ấn Connect

Chúng ta đã bắt đc các gói TCP gửi đến khi ấn Connect, đồng thời WireShark cũng bắt được và Show cụ thể các gói tin ra

Click vào gói tin đầu tiên và mình đã thấy cơ Syn được SET, như vậy gói tin mở đầu của việc bắt tay đã được gửi tới cho ENC28J60. Ngay bây giờ chúng ta phải viết hàm để phản hồi lại gói tin này bằng các việc sau:

  • Set cờ SYN và cơ ACK
  • Trường acknowledgment number = sequence number +1
  • sequence number = ngẫu nhiên

Mình sẽ tạo 1 Struct giống như đã tạo ở bài UDP và bỏ vào file tcp.h

Bắt đầu viết mã cho hàm TCP_read, mình sẽ debug từng tí một, trước tiên là kiểm cờ SYN

Tiếp tục dùng Hercules gửi thử 1 tin Connect

giao thức UDP

OK rồi, giờ phải phản hồi lại, để phản hồi thì phải tính kèm checksum, nên mình sẽ tạo hàm tính checksum cho giao thức TCP hen

checksum TCP

Checksum của TCP gồm toàn bộ gói TCP cộng thêm 8 byte IP, 2byte TCP length và 1 byte TCP Protocol ( tương tự gói checksum của UDP)

Quay trở lại với hàm TCP_read

Biên dịch và chạy lại mô phỏng. Bây giờ khi ấn Connect trên Herculess chúng ta đã kết nối thành công tới server 🙂

giao thức tcp enc28j60

WireShark cũng đã bắt lại toàn bộ quá trình !

Ngắt kết nối giao thức TCP

Hãy thử ấn Disconnect trên Hercules, bạn sẽ thấy ngay 1 gói tin với cờ FIN và ACK (Wikipedia nó không hề lừa mình 🙂 )

Tiếp tục bắt 2 cờ này và phản hồi lại nào ( cứ theo lí thuyết mà phang thôi 🙂 )

Tronng hàm TCP_read

Vẫn với phương châm test từng tí một. ! Tiếp tục test tiếp bằng debug

ngắt kết nối tcp en28j60

Rồi ! Giờ xóa dòng debug đi và gửi phản hồi lại

Code make header gần như copy y chang, chỉ sửa lại sequence numberacknowledgment number và tính lại checksum

Mình khai báo thêm uint32_t dat_ack ở đầu hàm

Giờ ngắt kết nối thử nhé

WireShark đã bắt được gói tin phản hồi ngắt kết nối của ENC28J60 (ACK)

Hiện tại mới chỉ Client ngắt kết nối thôi, server tiếp tục gửi cở FIN|ACK để ngắt kết nối pha thứ 2

Server phản hồi FIN|ACK và client trả lời lại ACK, hoàn tất đóng kết nối

Tóm tắt quy trình

Các bạn có thể tải file cho bài này tại đây

 

Từ tác giả:

Nếu có bất kì thắc mắc nào trong bài viết, vui lòng để lại comment dưới mỗi bài ! Mình sẽ không trả lời thắc mắc của các bạn ở facebook hay email !

Nếu trong phần code bạn nhìn thấy nhưng thứ kiểu như &amp; thì đó là lỗi hiển thị, cụ thể 3 kí tự < > & bị biến đổi thành như thế
&amp; là &
&lt;  là <
&gt; là >

Giới thiệu Đào Nguyện 80 bài viết
DIY,chế cháo, viết blog chia sẽ kiến thức về lập trình,điện tử - IoT. Rất mong được giao lưu, kết bạn với các bạn cùng đam mê. Địa chỉ Facebook: https://www.facebook.com/nguyendao207