Hàm TCPProcess:
Hàm này dài quá nên chỉ giải thích cấu trúc hàm cho các bạn dễ đọc thôi:
Khai báo các biến sử dụng:
Trỏ các biến con trỏ header IP và TCP đến vùng header tương ứng. Lúc này trên buffer đã có đầy đủ frame dữ liệu đọc từ ENC28J60.
Sau khi đọc được địa chỉ IP nguồn của host gửi và port nguồn, port đích, ta tìm kiếm trong TCP session table phiên TCP có sẵn tương ứng với gói tin này, nếu chưa tồn tại thì khởi tạo session mới:
Ta reset biến Timeout mỗi khi nhận được gói tin. Biến này nhằm phát hiện và hủy bỏ các phiên TCP bị “treo” một thời gian dài mà không nhận được dữ liệu.
Nếu cờ RST=1 (Reset). Đóng kết nối.
Tiếp theo, ta phải xử lý theo lưu đồ trạng thái của TCP. Ta dùng 1 cấu trúc switch…case để xử lý tùy vào trạng thái hiện tại của kết nối:
Trong mỗi trạng thái, ta xử lý thông tin trong header TCP và chuyển trạng thái tương ứng. Mọi người tự đọc nhé .
Hàm này dài quá nên chỉ giải thích cấu trúc hàm cho các bạn dễ đọc thôi:
Khai báo các biến sử dụng:
Code:
unsigned char i,ipHeaderLen,tcpHeaderLen; unsigned int dataLen; unsigned long tmp; struct ntIPHeader* ipHeader; struct ntTCPHeader* tcpHeader; unsigned char *tcpData;
Code:
//Khoi tao cac co tro den Header IP va TCP ipHeader = (struct ntIPHeader*)(buffer); ipHeaderLen = ((ipHeader->verHdrLen) & 0x0F) << 2; // tcpHeader = (struct ntTCPHeader*)(buffer+ipHeaderLen); tcpHeaderLen = ((tcpHeader->Offset) & 0xF0) >> 2; // tcpData = (buffer+ipHeaderLen+tcpHeaderLen); dataLen = HTONS(ipHeader->Len) - (ipHeaderLen + tcpHeaderLen);
Code:
if(i == TCP_MAX_SESSION){ //Neu khong co 1 phien TCP dang ton tai cho goi nay //Tim 1 phien dang o trang thai LISTEN (doi ket noi) cho local port nay for(i=0; i < TCP_MAX_SESSION; i++){ if(tcpSessionTable[i].sesState == TCP_STATE_LISTEN){ if(tcpSessionTable[i].srcPort == HTONS((tcpHeader->desPort))){ //If matched local port //Cap nhat remote port va remote IP tcpSessionTable[i].desPort = HTONS((tcpHeader->srcPort)); tcpSessionTable[i].desIP = HTONL((ipHeader->srcIPAddr)); //Dong thoi tao ra 1 session moi de cho ket noi khac den local port nay TCPCreateSession(tcpSessionTable[i].srcPort,tcpSessionTable[i].appDataIn); break; } } } } if(i == TCP_MAX_SESSION){ #ifdef TCP_DEBUG printf("No TCP session found\r\n"); #endif return; //Neu khong co phien TCP nao danh cho goi nay thi thoat ra } #ifdef TCP_DEBUG printf("TCP session found: %d\r\n",i); #endif
Code:
tcpSessionTable[i].timeOut = TCP_TIMEOUT; //Reset lai gia tri Time out
Code:
if ((tcpHeader->Flags) & TCP_RST_FLAG){ //Chap nhan dong ket noi TCPCloseSession(i); return; }
Code:
switch (tcpSessionTable[i].sesState){ //Neu la trang thai doi ket noi: TCP_STATE_LISTEN case(TCP_STATE_LISTEN): break; //Neu la trang thai TCP_STATE_SYN_RECEIVED case(TCP_STATE_SYN_RECEIVED): break; //Truong hop ket noi da duoc thiet lap case(TCP_STATE_ESTABLISHED): break; //Neu la trang thai doi LAST_ACK (2 phia deu san sang dong ket noi, dang doi xac nhan ack cuoi cung) case(TCP_STATE_LAST_ACK): break; //Truong hop ngat ket noi thu dong, da nhan co FIN tu remote host va xac nhan case(TCP_STATE_CLOSE_WAIT): break; //Truong hop dang o trang thai FIN WAIT 1 (da truyen du lieu xong, // san sang dong ket noi va da gui di co FIN va dang cho ACK) case(TCP_STATE_FIN_WAIT1): break; //Neu dang o trang thai FIN WAIT 2 (san sang dong ket noi va gui co FIN, // phia ben kia da xac nhan nhung van chua san sang dong ket noi case(TCP_STATE_FIN_WAIT2): break; case(TCP_STATE_TIMED_WAIT): break; case(TCP_STATE_CLOSING): break; default: TCPCloseSession(i); }
Comment