Thông báo

Collapse
No announcement yet.

Giao thức TCP/IP và Web server với AVR

Collapse
This is a sticky topic.
X
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • #31
    Đã nhỉ ! Giao diện web cũng đẹp nữa, vậy để CN tuần này vẽ cái mạch xong em up lên cho bà con làm theo luôn. Hjhj

    Email:
    Tel: 0983.497.310

    Comment


    • #32
      Bài 5: Các giao thức lớp vận chuyển
      Vậy là xong các giao thức ở lớp 3, IP và giao thức hỗ trợ cho nó là ARP. Bây giờ chúng ta sẽ chuyển sang các giao thức ở lớp 4, lớp vận chuyển (Transport Layer). Đó là TCP (Transport Control Protocol) và UDP (User Datagram Protocol), ngoài ra còn có một giao thức điều khiển cũng có thể xếp vào đây, đó là ICMP (Internet Control Message Protocol).

      Trước hết ta nói qua về chức năng và hoạt động cơ bản của các giao thức này trước khi bắt tay vào viết code.
      Nếu nói phần lập trình giao thức IP phức tạp gấp đôi so với ethernet thì có lẽ lập trình giao thức TCP phải phức tạp gấp đôi cả IP và ARP cộng lại. Vì trong giao thức TCP, ta phải xử lý các vấn đề liên quan đến quá trình bắt tay giữa hai phía khi truyền dữ liệu. Phải hỗ trợ cùng lúc nhiều kết nối TCP đến các host khác (ví dụ webserver phải có khả năng xử lý khi có đồng thời vài ba máy tính cùng truy cập vào website), và liên quan chặt chẽ đến lớp ứng dụng và dịch vụ. Chính vì vậy ta phải tìm hiểu kỹ hoạt động của nó.

      So với TCP thì UDP đơn giản hơn nhiều.

      Còn ICMP là một giao thức dùng để chuyển qua lại các bản tin điều khiển trên mạng. Ví dụ khi ta gõ lệnh ping trên máy tính, sẽ có 1 bản tin điều khiển là ICMP request được gửi đến địa chỉ đích. Và nơi nhận được ICMP request sẽ trả lời lại bằng bản tin ICMP reply. Nếu viết xong giao thức này thì chúng ta có thể ping đến board mạch của chúng ta được rồi.


      Có lẽ ta bắt đầu với giao thức ICMP.

      Giao thức thông điệp điều khiển Internet (Internet Control Message Protocol) được các router và host trên mạng Internet sử dụng để thông báo về các vấn đề gặp phải trong quá trình định tuyến dữ liệu.
      Việc này được thực hiện bằng cách gửi qua lại các bản tin thông báo về các sự kiện xảy ra trên mạng. Các bản tin này được gọi là thông điệp điều khiển Internet (Internet Control Message). Có rất nhiều bản tin như vậy, được dùng trong những trường hợp cụ thể khác nhau. Dưới đây là 1 số bản tin ICMP thường gặp:

      - Bản tin “Echo Request” và “Echo Reply”: sử dụng cho quá trình kiểm tra (lệnh ping).
      - Bản tin “Source Quench”: yêu cầu host nguồn giảm tốc độ truyền dữ liệu.
      - Bản tin “Destination Unreachable”: thông báo cho host nguồn biết datagram không thể chuyển được đến đích.
      - Bản tin “Time Exceeded”: thông báo 1 gói tin bị hủy do TTL = 0.
      - Bản tin “Fragmentation Needed”: thông báo cho host nguồn biết 1 datagram có cờ DF (Don’t Fragment) = 1, nhưng router cần phân đoạn datagram này để chuyển đến chặng kế tiếp.

      Trong phạm vi project này, chúng ta chỉ lập trình cho 2 bản tin là “Echo Request” và “Echo Reply” để phục vụ cho việc ping đến board mạch của chúng ta.

      Đây là cấu trúc của bản tin ICMP:

      Bản tin ICMP gồm 8 byte:
      - Byte đầu là trường Type: cho biết đây là bản tin gì.
      - Byte thứ 2 là Code: cho biết mã cụ thể cho từng trường hợp.
      - 2 byte kế là checksum: kiểm tra lỗi.
      - 4 byte còn lại chứa thông tin riêng của từng loại bản tin. Trong trường hợp bản tin “Echo Request” và “Echo Reply” thì đây là số nhận dạng (ID) và số tuần tự của bản tin.
      Vậy ta cần khai báo cấu trúc của bản tin ICMP vào trong file “packet.h”:
      Code:
      //--------------------------------------------------------------------------------------
      //Cau truc ICMP header
      struct ntICMPHeader
      {
      	unsigned char	Type;
      	unsigned char	Code;
      	unsigned int	Checksum;
      	unsigned int	ID;
      	unsigned int	seqNumber;
      };
      #define ICMP_HEADER_LEN	8
      #define ICMP_TYPE_ECHOREPLY		0
      #define ICMP_TYPE_ECHOREQUEST	8
      Tiếp theo ta tạo file source và file header cho module giao thức ICMP.
      Nội dung ban đầu của file “icmp.c”
      Code:
      //----------------------------------------------------------------------------
      // Writen by NTTam - PTITHCM
      //----------------------------------------------------------------------------
      #include "packet.h"
      #include "ethernet.h"
      #include "arp.h"
      #include "ip.h"
      #include "icmp.h"
      Và file “icmp.h”
      Code:
      //----------------------------------------------------------------------------
      // Writen by NTTam - PTITHCM
      //----------------------------------------------------------------------------
      //======================================================================================
      //									icmp.h
      //======================================================================================
      //	This is header file for icmp.c
      //		Writen by NTTam
      //		PTITHCM
      //		Ver 1.0
      //======================================================================================
      #ifndef ICMP_H
      #define ICMP_H
      //--------------------------------------------------------------------------------------
      #include "packet.h"
      //--------------------------------------------------------------------------------------
      
      #endif //ICMP_H
      Bây giờ ta bắt tay vào viết code:
      Đầu tiên là hàm xử lý khi nhận được bản tin “Echo Request” (tức là có máy tính “ping” đến board mạch.
      Code:
      //--------------------------------------------------------------------------------------
      //Ham xu ly goi ICMP nhan duoc
      void icmpIpIn(struct ntIPHeader* ipHeader)
      {
      	struct ntICMPHeader* icmpHeader;
      	icmpHeader = (struct ntICMPHeader*)((unsigned char*)ipHeader + IP_HEADER_LEN);
      	// check ICMP type
      	switch(icmpHeader->Type)
      	{
      	case ICMP_TYPE_ECHOREQUEST:
      		// echo request
      		icmpEchoReply(ipHeader);
      		break;
      	default:
      		break;
      	}
      }
      Chức năng hàm này khá đơn giản: ta kiểm tra trường “Type” để xem đây có đúng là bản tin “Echo Request” hay không. Nếu đúng ta gọi hàm icmpEchoReply (sẽ viết kế tiếp) để trả lời.

      Tiếp theo là hàm icmpEchoReply để gửi bản tin “Echo Reply” để trả lời cho bản tin “Echo Request”
      Code:
      //--------------------------------------------------------------------------------------
      //Ham gui di ban tin tra loi cho Echo Request (Echo Reply)
      void icmpEchoReply(struct ntIPHeader* ipHeader)
      {
      	unsigned long tempIp;
      	unsigned char* ethFrame;
      	struct ntICMPHeader* icmpHeader;
      	icmpHeader = (struct ntICMPHeader*)((unsigned char*)ipHeader + IP_HEADER_LEN);
      	icmpHeader->Type = ICMP_TYPE_ECHOREPLY;
      	icmpHeader->Checksum = 0;
      	icmpHeader->Checksum = ipChecksum((unsigned char*)icmpHeader, HTONS(ipHeader->Len)-IP_HEADER_LEN);
      	tempIp = ipHeader->desIPAddr;
      	ipHeader->desIPAddr = ipHeader->srcIPAddr;
      	ipHeader->srcIPAddr = tempIp;
      	ethFrame = ((unsigned char*)ipHeader);
      	ethFrame -= ETH_HEADER_LEN;
      	arpIpOut(ethFrame, 0);
      	#ifdef ICMP_DEBUG
      	icmpPrintHeader(ipHeader);
      	#endif
      	ethSendFrame(HTONS(ipHeader->Len)+ETH_HEADER_LEN, ethFrame);
      }
      Nội dung thực hiện trong hàm này khá đơn giản:
      - Ta điền các nội dung cần thiết cho bản tin Echo Reply.
      - Gọi giao thức ARP để phân giải địa chỉ
      - Gọi hàm ethSendFrame của giao thức ethernet để gửi frame ethernet đi.

      Cuối cùng là 1 hàm dùng cho mục đích debug:
      Code:
      //--------------------------------------------------------------------------------------
      #ifdef ICMP_DEBUG
      //In ra Header cua goi ICPM
      void icmpPrintHeader(struct ntIPHeader* ipHeader)
      {
      	struct ntICMPHeader* icmpHeader;
      	icmpHeader = (struct ntICMPHeader*)((unsigned char*)ipHeader + IP_HEADER_LEN);
      	printf("ICMP Packet:\r\n");
      	// print source IP address
      	printf("SrcIpAddr: ");	ipPrintAddr(HTONL(ipHeader->srcIPAddr));	printf("\n\r");
      	// print dest IP address
      	printf("DstIpAddr: ");	ipPrintAddr(HTONL(ipHeader->desIPAddr));	printf("\n\r");
      	// print type
      	printf("Type   : ");
      	switch(icmpHeader->Type)
      	{
      	case ICMP_TYPE_ECHOREQUEST:		printf("ECHO REQUEST"); break;
      	case ICMP_TYPE_ECHOREPLY:		printf("ECHO REPLY"); break;
      	default:						printf("UNKNOWN"); break;
      	}
      	printf("\n\r");
      	// print code
      	printf("Code: 0x%x \n\r",(unsigned int)(icmpHeader->Code));
      }
      #endif
      //--------------------------------------------------------------------------------------
      Ta cũng phải nhớ thêm declare các hàm vừa viết vào file header (icmp.h):
      Code:
      void icmpIpIn(struct ntIPHeader* ipHeader);
      void icmpEchoReply(struct ntIPHeader* ipHeader);
      void icmpPrintHeader(struct ntIPHeader* ipHeader);
      Vậy là xong giao thức ICMP.
      Đến đây vẫn chưa ping được nhé, vì ta vẫn chưa viết ngắt timer để phục vụ cho các hàm kiểm tra thời gian timeout và nội dung cho chương trình chính (main()).
      Last edited by nttam79; 04-11-2011, 16:28.

      Comment


      • #33
        Nguyên văn bởi duongbo
        Em chào thầy. Em cảm ơn bài viết của thầy rất nhiều. Có 1 điều em thắc mắc đó là giao tiếp giữa AVR với ENC28J60 dùng SPI.
        +Theo sơ đồ nguyên lý của thầy thì atmega32 dùng 5V, còn ENC28J60 dùng 3,3V. Như vậy khi avr xuất dữ liệu và clock trên trân MOSI, SCK thì chip ENC28J60 có bị sao không ( ý của em là chân avr xuất ra 5V trong khi đó ENC chỉ dùng nguồn 3,3V thì chip ENC có bị vấn đề gì không)
        + Khi ENC truyền dữ liệu về avr qua chân MISO với điện áp là 3,3V còn avr nhận 3,3V vẫn được coi là mức 1 đúng không ạ.
        Không sao cả, tuy ENC28J60 chạy với nguồn 3V3 nhưng các IO của nó là 5v tolerant, tức là có thể nhận input 5V như thường.
        Khi ENC28J60 truyền sang AVR, mức logic 1 là 3V3 đủ để AVR nhận ra đó là logic 1 (ngưỡng là khoảng 2V5, trên mức đó thì xem là logic 1).

        Comment


        • #34
          ban đầu đọc đã thấy ngợ ngợ là ai
          xem video mới biết là thầy, và vợ bên thuysinh.org
          em đã đọc bài của thầy bên Điều khiển hồ thủy sinh qua mạng Internet - Page 12 - TSO - Cộng đồng thủy sinh online
          bjo thầy nói bên tut này thấy hay quá!
          chúc thầy sức khỏe và hạnh phúc!
          p/s: bể cá của thầy rất đẹp!!!

          Comment


          • #35
            Phụ anh Tâm một tay nên hôm nay vẽ lại cái mạch nguyên lý bằng IC DIP cho bà con làm tại gia nè. Khi nào layout up lên sau nhé các bác.

            Sửa lại theo góp ý của anh Tâm.
            Attached Files
            Last edited by tienhuypro; 05-11-2011, 23:59.

            Email:
            Tel: 0983.497.310

            Comment


            • #36
              Nguyên văn bởi tienhuypro Xem bài viết
              [ATTACH=CONFIG]34970[/ATTACH]
              [ATTACH]34973[/ATTACH]
              Phụ anh Tâm một tay nên hôm nay vẽ lại cái mạch nguyên lý bằng IC DIP cho bà con làm tại gia nè. Khi nào layout up lên sau nhé các bác.
              Thanks bạn tienhuypro nhé. Anh đã xem mạch của em rồi, mạch rất OK. Nhưng anh đề nghị bổ sung một tí cho tiện dụng hơn trước khi làm layout nhé:
              1-Thêm 2 button nữa. Vì khi ta duyệt hệ thống menu trên LCD thì cần ít nhất 6 nút: UP, DOWN (để chọn menu), ENTER, CANCEL (để vào ra menu) và LEFT, RIGHT để di chuyển khi edit ngày tháng trong menu chẳng hạn.
              2-Đưa các IO còn trống của ATmega ra một Header, để mọi người có thể làm các board ngoại vi kết nối vào điều khiển gì đó.
              3-Cảm biến nhiệt độ dùng LM35 sẽ chính xác hơn (và cũng tốn tiền hơn)
              4-Cuối cùng, lưu ý thứ tự các chân trên header dùng để nạp chương trình nhé, không biết mọi người dùng mạch nạp nào nên không dám có ý kiến, tuy nhiên theo mạch ở trang đầu thì có thứ tự chân giống của mạch nạp AVR STK mà TME bán.

              Một lần nữa cảm ơn tienhuypro đã cung cấp mạch cho mọi người để làm project này.
              Last edited by nttam79; 05-11-2011, 22:43.

              Comment


              • #37
                Thầy ạ!
                em đang buil theo chương trình của thầy
                nhưng đến đoạn này thì báo lỗi:
                prog_char enc28j60_config[44] PROGMEM = {
                ETXSTL, LO8(TXSTART_INIT), //start lo
                ETXSTH, HI8(TXSTART_INIT), //start hi
                ETXNDL, LO8(TXSTOP_INIT ), //end lo
                ETXNDH, HI8(TXSTOP_INIT ), //end hi

                ERXSTL, LO8(RXSTART_INIT), //start lo
                ERXSTH, HI8(RXSTART_INIT), //start hi
                ERXNDL, LO8(RXSTOP_INIT ), //end lo
                ERXNDH, HI8(RXSTOP_INIT ), //end hi

                MACON2, 0x00,
                MACON1, (MACON1_MARXEN | MACON1_RXPAUS | MACON1_TXPAUS),
                MACON3, ( MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN),
                MAMXFLL, LO8(1518),
                MAMXFLH, HI8(1518),
                MABBIPG, 0x12, //half duplex
                MAIPGL, 0x12,
                MAIPGH, 0x0C, //half duplex

                MAADR5, ENC28J60_MAC0,
                MAADR4, ENC28J60_MAC1,
                MAADR3, ENC28J60_MAC2,
                MAADR2, ENC28J60_MAC3,
                MAADR1, ENC28J60_MAC4,
                MAADR0, ENC28J60_MAC5
                };
                nó báo là LO8 và HI8 chưa được định nghĩa
                thầy giải thích thêm cho em và các bạn đoạn này nhé!
                cảm ơn thầy nhiều!

                Comment


                • #38
                  Nguyên văn bởi hieppro89 Xem bài viết
                  Thầy ạ!
                  em đang buil theo chương trình của thầy
                  nhưng đến đoạn này thì báo lỗi:

                  nó báo là LO8 và HI8 chưa được định nghĩa
                  thầy giải thích thêm cho em và các bạn đoạn này nhé!
                  cảm ơn thầy nhiều!
                  Bạn đọc tiếp xuống đoạn dưới có hướng dẫn define các macro này trong file "ntAVRnet.h" sau đó nhớ include file này là OK.

                  Comment


                  • #39
                    sorry thầy và các bạn!
                    em chưa buil tiếp đoạn sau trong : ntAVRnet.h
                    trong đó thầy có định nghía LO và HI
                    nên báo lỗi là đúng
                    bây chừ thì ok rồi
                    chúc các bạn học tốt!đang háo hức tìm hiểu
                    //----------------------------------------------------------------------------
                    // Writen by NTTam - PTITHCM
                    //----------------------------------------------------------------------------
                    #ifndef NTAVRNET_H
                    #define NTAVRNET_H

                    #ifndef F_CPU
                    #define F_CPU 12000000 // Cho toc do la 12MHz
                    #endif //F_CPU
                    #define CYCLES_PER_US ((F_CPU+500000)/1000000) //So chu ky lenh trong 1 micro giay

                    #define LO8(x) ((x)&0xFF)
                    #define HI8(x) (((x)>>8)&0xFF)

                    #endif //NTAVRNET_H
                    P/S: em đang học mạng máy tính, ko nhìu lý thuyết lắm, chủ yếu IPV4 và 6
                    nhưng thực hành lại là Packet Tracer 5.0, chỉ cấu hình Router và NAT
                    nên em chưa hiểu về quá trình truyền nhận dữ liệu trên internet như thế nào
                    bài viết của thầy thật hay, giúp em hiểu về quá trình này như thế nào
                    có time phải xem thử Wireshark ngay, vì em thấy thầy bảo nó là phần mềm phân tích gói tin
                    cảm ơn thầy nhìu!
                    Last edited by hieppro89; 05-11-2011, 22:57.

                    Comment


                    • #40
                      Thầy cho thêm chú thích vào mấy thanh ghi nữa thầy ơi.Điều này giúp em và các bạn khác hiểu được bản chất con enc28J60.Hiện tại em chỉ biết hì hục đọc datasheet con enc28j60.Chứ chưa dám động đến code của thầy.Em xin chân thành cảm ơn!.
                      , , ,

                      Comment


                      • #41
                        Nguyên văn bởi rptdnmqs Xem bài viết
                        Thầy cho thêm chú thích vào mấy thanh ghi nữa thầy ơi.Điều này giúp em và các bạn khác hiểu được bản chất con enc28J60.Hiện tại em chỉ biết hì hục đọc datasheet con enc28j60.Chứ chưa dám động đến code của thầy.Em xin chân thành cảm ơn!.
                        Có thời gian tôi sẽ viết chú thích thêm, hiện giờ cũng hơi bận với lại lười biếng vì tập thanh ghi của enc28J60 nhiều quá, với lại tất cả có thể tham khảo trong dấtheet mà, chịu khó đọc tiếng anh tí thôi .

                        Comment


                        • #42
                          "Nguyên văn bởi rptdnmqs

                          Thầy cho thêm chú thích vào mấy thanh ghi nữa thầy ơi.Điều này giúp em và các bạn khác hiểu được bản chất con enc28J60.Hiện tại em chỉ biết hì hục đọc datasheet con enc28j60.Chứ chưa dám động đến code của thầy.Em xin chân thành cảm ơn!."
                          Nguyên văn bởi nttam79 Xem bài viết
                          Có thời gian tôi sẽ viết chú thích thêm, hiện giờ cũng hơi bận với lại lười biếng vì tập thanh ghi của enc28J60 nhiều quá, với lại tất cả có thể tham khảo trong dấtheet mà, chịu khó đọc tiếng anh tí thôi .
                          Anh Tâm nói đúng rùi, tất cả điều có trong datasheet mà. Bài này anh Tâm chủ yếu tập trung vào thuật toán xử lý giữa VĐK và Ethernet. Code thì chúng ta không quan tâm nhiều lắm vì đã có hết rùi. Mong anh Tâm dành chút thời gian viết tiếp chủ đề này vì có nhiều bạn đang chờ từng ngày và bản thân em cũng vậy. Thanks anh!

                          Email:
                          Tel: 0983.497.310

                          Comment


                          • #43
                            Em cũng biết là thế nhưng nó nói kô chi tiết nên có 1 số thanh ghi kô hiểu được.Chứ còn đọc hiểu được datasheet thì việc code cũng kô là vấn đề.Thanks!
                            , , ,

                            Comment


                            • #44
                              Đã layout xong mạch nhưng không đẹp lắm, kích thước đường mạch là 20mil up lên cho anh em ủi nè.
                              Ai không ưng ý thì có thể layout lại. Huy gởi kèm theo file nguyên lý và file .MAX bên dưới luôn đó nha
                              Attached Files
                              Last edited by tienhuypro; 06-11-2011, 20:22.

                              Email:
                              Tel: 0983.497.310

                              Comment


                              • #45
                                Giao thức TCP (Transport Control Protocol):

                                Tiếp theo là giao thức khó chịu nhất trong chồng giao thức TCP/IP. Đó chính là giao thức TCP (Transport Control Protocol)

                                Nhiệm vụ chính của TCP là đảm bảo dữ liệu đến đích đúng và đủ trên một môi trường truyền tải không đáng tin cậy (IP).

                                Để hiểu chức năng và cách mà TCP thực hiện chức năng đó, ta xem minh họa sau đây:



                                Đến đây có 3 trường hợp xảy ra:
                                - TH 1: mọi việc suôn sẻ, thư ký bên B nhận được thư, gửi thư trả lời báo đã nhận được thông điệp. Thư ký bên A sẽ hủy bản photo còn lưu dữ, việc gửi thông điệp thành công.
                                - TH2: bưu điện làm mất thư, bên B không nhận được. Như vậy thư ký bên A chờ 1 thời gian không thấy phản hồi sẽ lấy bản photo ra gửi lại lần nữa.
                                - TH 3: thư ký bên B đã nhận được và gửi thư báo nhận, nhưng bưu điện lại làm thất lạc thư này. Thư ký bên A được một thời gian không thấy cũng sẽ gửi lại. Khi bên B nhận được thông điệp một lần nữa cũng sẽ gửi báo nhận một lần nữa.

                                Cấu trúc Header TCP:



                                Chú thích:
                                - Số port đích và số port nguồn: để phân biệt các tiến trình ứng dụng đang xảy ra trong máy tính
                                - Các số sequence và Acknowledgement: số sequence để phân biệt các segment khác nhau trong một dòng dữ liệu, các số Acknowledgement dùng trong cơ chế xác nhận
                                - Vùng Data offset: chiều dài của Header tính theo đơn vị 32 bit
                                - Một số cờ (flags):
                                . URG (Urgent): thiết lập 1 khi có dữ liệu quan trọng cần truyền ngay.
                                . ACK: cho biết có số xác nhận nằm trong vùng Acknowledgement
                                . PSH (Push): được thiết lập trong trường hợp dữ liệu nên được giao tức thời
                                . RST (Reset): chỉ thị một lỗi sai và hủy bỏ phiên làm việc
                                . SYN (Synchronize): trong các bản tin khởi tạo khi thiết lập một kết nối truyền dữ liệu
                                . FIN (Finish): dùng đóng 1 phiên làm việc
                                - Vùng Window: chỉ ra số lượng không gian bộ đệm khả dụng để nhận dữ liệu
                                - Vùng Checksum: vùng kiểm tra sai cho cả segment
                                - Vùng Urgent Pointer: chỉ ra chiều dài của dữ liệu urgent
                                - Vùng Options: xác định kích thước cực đại của 1 segment

                                Cụ thể hơn, vai trò của TCP trong chồng giao thức TCP gồm 3 chức năng chính: điều khiển luồng, kiểm soát lỗi và báo nhận.
                                - Điều khiển luồng: điều phối tốc độ và kích thước luồng dữ liệu để đảm bảo phía nhận đủ khả năng nhận và xử lý luồng dữ liệu.
                                - Kiểm soát lỗi: đảm bảo các gói tin đến đúng và đủ
                                - Báo nhận: khi nhận được dữ liệu và không có lỗi, phía nhận phải báo lại với phía gửi biết.

                                Để thực hiện được các chức năng đó, một quá trình truyền dữ liệu qua giao thức TCP (mà ta gọi là phiên truyền thông – session) gồm có 3 giai đoạn:
                                - Thiết lập kết nối
                                - Truyền dữ liệu
                                - Giải tỏa kết nối

                                Để có thể hình dung được quá trình đó, mời các bạn xem minh họa sau:
                                Thiết lập kết nối:


                                Truyền dữ liệu:


                                Giải tỏa kết nối:


                                Bây giờ ta liên hệ với các trường trong TCP Header nhé:






                                Để có thể giám sát chặt chẽ trạng thái và mọi sự kiện xảy ra trong 1 kết nối TCP, trạng thái của một kết nối TCP được chuyển đổi tuân theo một lưu đồ trạng thái như sau:



                                Đây chính là thuật toán chính mà ta phải lập trình cho giao thức TCP. Nhìn thấy sợ chưa .


                                Giải thích:
                                - TCP là giao thức hướng kết nối, dạng client – server. Tức là trong 1 phiên truyền thông thì sẽ có một phía đóng vai trò client (chính là phía khởi tạo kết nối, trong ví dụ minh họa trên là công ty A, bên trái), phía còn lại, lúc nào cũng ở trạng thái chờ đợi các client thiết lập kết nối tới chính là server.
                                - Ví dụ khi ta truy cập web, thì máy tính của ta là client, máy chủ chứa trang web chính là server, lúc nào cũng ở trạng thái đợi các máy tính client kết nối đến (và phải có khả năng thiết lập đồng thời nhiều kết nối, vì có thể có nhiều client kết nối tới cùng lúc).
                                - Đối với mạch mà chúng ta định làm, dĩ nhiên là thông thường nó đóng vai trò server rồi.
                                - Trong lưu đồ trên, áp dụng cho cả client và server. Cả client và server đều bắt đầu bằng trạng thái “Close”. Client sẽ thiết lập kết nối theo con đường Active Open (nó chủ động thiết lập kết nối). Server sẽ thiết lập kết nối theo con đường Passive Open (thụ động, vì nó đợi client bắt đầu mà)

                                Quá trình chuyển trạng thái: ta hãy xem xét kịch bản thông thường nhất.
                                - Cả hai bắt đầu bằng trạng thái close, không có kết nối nào tồn tại.
                                - Khi Server mở một port TCP để đợi client thiết lập kết nối, nó chuyển sang trạng thái “Listen”.
                                - Khi client gửi đi bản tin SYN (bước số 1 trong ví dụ minh họa, giai đoạn thiết lập kết nối), nó chuyển sang trạng thái “SYN sent”.
                                - Lúc này khi server nhận được bản tin SYN từ client và gửi đáp lại 1 bản tin SYN (bước 2 trong VD), nó chuyển sang trạng thái “SYN Received”.
                                - Lúc này client gửi lại bản tin xác nhận ACK (bước 3 trong ví dụ), nó chuyển sang trạng thái thiết lập kết nối “Established”.
                                - Server nhận được bản tin ACK trên của client, nó cũng chuyển sang trạng thái “Established”.
                                - Sau đó 2 bên tiến hành truyền dữ liệu, trạng thái cả 2 phía đều là “Established”.
                                - Một trong hai phía truyền xong dữ liệu, đến đây thì vai trò hai bên là như nhau, ta giả sử client truyền xong dữ liệu trước, nó sẽ gửi bản tin FIN, và chuyển sang trạng thái “FIN wait 1”.
                                - Phía server nhận được bản tin này, gửi xác nhận ACK, và chuyển sang trạng thái “Close wait”.
                                - Khi client nhận được xác nhận từ server (nhận được bản tin ACK trên) thì nó chuyển sang trạng thái “FIN wait 2”.
                                - Đến lúc này server vẫn có thể tiếp tục gửi dữ liệu và client vẫn tiếp tục nhận (vì chỉ có client báo là gửi xong dữ liệu).
                                - Đến khi nào server cũng gửi hết dữ liệu, nó sẽ gửi đi bản tin FIN, cho biết nó cũng đã gửi xong dữ liệu và chuyển sang trạng thái “LAST ACK”.
                                - Khi client nhận được bản tin FIN trên từ server, nó gửi xác nhận (ACK) và chuyển sang trạng thái “Time wait”, sau đó chờ 1 khoảng thời gian Timeout và đóng kết nối, quay lại trạng thái “Close”.
                                - Khi server nhận được nó cũng chuyển từ “Last ACK” sang “Close” (không cần đợi Timeout)

                                Trên đây chỉ là kịch bản thông thường nhất. Lưu đồ trên còn giải quyết cho các kịch bản khác.
                                Last edited by nttam79; 07-11-2011, 01:12.

                                Comment

                                Về tác giả

                                Collapse

                                nttam79 Tìm hiểu thêm về nttam79

                                Bài viết mới nhất

                                Collapse

                                Đang tải...
                                X