⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.lst

📁 基于51单片机和RTL8019以太网控制器的嵌入式以太网控制程序。
💻 LST
📖 第 1 页 / 共 5 页
字号:
 363   5                                              {
 364   6                                                 index=j;
C51 COMPILER V8.02   TCP                                                                   09/21/2006 20:16:32 PAGE 7   

 365   6                                                 // Initialize new connection
 366   6                                                 conxn[index].state=STATE_LISTEN;
 367   6                                                 conxn[index].socket_type=SERVER;
 368   6                                                 break;
 369   6                                              }
 370   5                                       }
 371   4                                       //所有的连接都被占有,则丢弃该包
 372   4                                       if (NO_CONNECTION==j) return;
 373   4                              }
 374   3                              else
 375   3                                      return;
 376   3                        }
 377   2                      //保证程序不出错
 378   2                      if (index > NO_CONNECTION-1)
 379   2                      {
 380   3      //                      if (debug) PrintStr("TCP: Error in assigning conxn number\r");
 381   3                              return;
 382   3                      }
 383   2                      //检查收到的包的序列号是否出错
 384   2                      if (pRxdnet->tcpframe.seqnumber > 0xFFFFFF00L)
 385   2                      {
 386   3      //                      if (debug) PrintStr("TCP: Rcvd a high sequence number\r");      
 387   3                              InerClose(index);
 388   3                              tcp_send(&TCPSend,FLG_RST, 20, NO_CONNECTION);
 389   3                              return;
 390   3                      }
 391   2                      if (pRxdnet->tcpframe.control & FLG_RST)
 392   2                      {
 393   3                              // An RST does not depend on state at all.  And it does
 394   3                              // not count as data so do not send an ACK here.  Close
 395   3                              // connection
 396   3      //                      if (debug) PrintStr("TCP: Rcvd a reset\r");
 397   3                              InerClose(index);
 398   3                              return;
 399   3                      }
 400   2                      else if (pRxdnet->tcpframe.control & FLG_SYN)
 401   2                      {
 402   3                              //收到一个SYN+ACK包,则该包只有在STATE_SYN_SEND时才有效
 403   3                              //由Mingtree添加,以适应当单片机为客户端时的情况
 404   3                              if(pRxdnet->tcpframe.control & FLG_ACK)
 405   3                              {
 406   4                                      if (conxn[index].state != STATE_SYN_SENT)
 407   4                                      {
 408   5      //                                      if (debug) PrintStr("TCP: Error, rcvd bogus SYN AND ACK\r");
 409   5                                              tcp_send(&TCPSend,FLG_RST, 20, NO_CONNECTION);
 410   5                                              return;
 411   5                                      }
 412   4                              }
 413   3      
 414   3                              // A SYN segment only makes sense if connection is in LISTEN
 415   3                              else if ((conxn[index].state != STATE_LISTEN) &&
 416   3                                      (conxn[index].state != STATE_CLOSED))
 417   3                              {
 418   4      //                              if (debug) PrintStr("TCP: Error, rcvd bogus SYN\r");
 419   4                                      InerClose(index);
 420   4                                      tcp_send(&TCPSend,FLG_RST, 20, NO_CONNECTION);
 421   4                                      return;
 422   4                              }
 423   3                      }
 424   2                      else if ((pRxdnet->tcpframe.control & FLG_ACK) == 0)
 425   2                      {
 426   3                              // Incoming segments except SYN or RST must have ACK bit set
C51 COMPILER V8.02   TCP                                                                   09/21/2006 20:16:32 PAGE 8   

 427   3                              // See TCP/IP Illustrated, Vol 2, Page 965
 428   3                              // Drop segment but do not send a reset
 429   3      //                      if (debug) PrintStr("TCP: Error, rcvd segment has no ACK\r");
 430   3                              return;
 431   3                      }
 432   2                      // Compute length of header including options, and from that
 433   2                      // compute length of actual data
 434   2                      //计算头部长度,并计算实际长度
 435   2                      header_len=(pRxdnet->tcpframe.offset&0xF0)>>2;
 436   2                      data_len=pRxdnet->ipframe.totallength-((pRxdnet->ipframe.verandihl& 0x0F)*4)-header_len;
 437   2                      packACK = pRxdnet->tcpframe.acknumber;
 438   2                      packSeq = pRxdnet->tcpframe.seqnumber;
 439   2                      // Handle TCP state machine for this connection
 440   2                      switch (conxn[index].state)
 441   2                      {
 442   3                              case STATE_CLOSED:
 443   3                              case STATE_LISTEN:
 444   3                                      // If incoming segment contains SYN and no ACK, then handle
 445   3                                      if ((pRxdnet->tcpframe.control & FLG_SYN) && ((pRxdnet->tcpframe.control & FLG_ACK) == 0))
 446   3                                      {
 447   4                                              // Capture his starting sequence number and generate
 448   4                                              // my starting sequence number
 449   4                                              // Fill in connection information
 450   4                                              conxn[index].ip.words[0]= pRxdnet->ipframe.sourceip[0];
 451   4                                              conxn[index].ip.words[1]= pRxdnet->ipframe.sourceip[1];
 452   4                                              conxn[index].port = pRxdnet->tcpframe.sourceport;
 453   4                                              conxn[index].state = STATE_LISTEN;
 454   4                                              conxn[index].his_sequence = 1 + packACK;
 455   4                                              conxn[index].his_ack = packSeq;
 456   4      
 457   4                                              // Use system clock for initial sequence number
 458   4                                              EA = 0;
 459   4                                              conxn[index].my_sequence = initial_sequence_nr;
 460   4                                              initial_sequence_nr += 64000L;
 461   4                                              EA = 1;
 462   4      
 463   4                                              // Send header options with the next message
 464   4                                              // Since timestamps are optional and we do not use
 465   4                                              // them, do not have to send them
 466   4                                              // After sending the SYN ACK the client browser will
 467   4                                              // blast me with 2 messages, an ACK, and a HTTP GET
 468   4                                              tcp_send(&TCPSend,FLG_SYN | FLG_ACK, 28, index);
 469   4      
 470   4                                              // My SYN flag increments my sequence number
 471   4                                              // My sequence number is always updated to point to
 472   4                                              // the next byte to be sent.  So the incoming ack
 473   4                                              // number should equal my sequence number
 474   4                                              conxn[index].my_sequence++;
 475   4      
 476   4                                              conxn[index].state = STATE_SYN_RCVD;
 477   4      //                                      if (debug) PrintStr("TCP: Entered SYN RCVD state\r");
 478   4                                      }
 479   3                                      else
 480   3                                      {
 481   4                                              // Sender is out of sync so send reset
 482   4                                              InerClose(index);
 483   4                                              tcp_send(&TCPSend,FLG_RST, 20, NO_CONNECTION);
 484   4                                      }
 485   3                                      break;
 486   3      
 487   3                              case STATE_SYN_RCVD:
 488   3                                      // He may already be sending me data - should process it
C51 COMPILER V8.02   TCP                                                                   09/21/2006 20:16:32 PAGE 9   

 489   3                                      conxn[index].his_sequence += data_len;
 490   3                                      conxn[index].his_ack = packACK;
 491   3      
 492   3                                      if (pRxdnet->tcpframe.control & FLG_FIN)
 493   3                                      {
 494   4                                              // His FIN counts as a byte of data
 495   4                                              conxn[index].his_sequence++;
 496   4                                              tcp_send(&TCPSend,FLG_ACK, 20, index);
 497   4                                              conxn[index].state = STATE_CLOSE_WAIT;
 498   4      //                                      if (debug) PrintStr("TCP: Entered CLOSE_WAIT state\r");
 499   4      
 500   4                                      // At this point we would normally wait for the application
 501   4                                              // to close.  For now, send FIN right away.
 502   4                                              tcp_send(&TCPSend,FLG_FIN | FLG_ACK, 20, index);
 503   4                                              conxn[index].my_sequence++;   // For my FIN
 504   4                                              conxn[index].state = STATE_LAST_ACK;
 505   4      //                                      if (debug) PrintStr("TCP: Entered LAST ACK state\r");
 506   4                                      }
 507   3      
 508   3                                      // Make sure he is ACKing my SYN
 509   3                                      else if (packACK == conxn[index].my_sequence)
 510   3                                      {
 511   4                                              conxn[index].state = STATE_ESTABLISHED;
 512   4      //                                      if (debug) PrintStr("TCP: Entered ESTABLISHED state\r");
 513   4                                              // If sender sent data ignore it and he will resend
 514   4                                              // Do not send response because we received no
 515   4      
 516   4                                              //--------------------------------------------------------
 517   4                                              //
 518   4                                              //                                      进入连接状态,可以发送数据
 519   4                                              //
 520   4                                              //--------------------------------------------------------
 521   4                                              //调用服务器OnConnect()回调函数,该函数在TCPListen时被实体化
 522   4                                              (* conxn[index].connect)();
 523   4                                      }
 524   3                                      break;
 525   3                              case STATE_ESTABLISHED:
 526   3                                      conxn[index].his_ack = packACK;
 527   3      
 528   3                                      if (pRxdnet->tcpframe.control & FLG_FIN)
 529   3                                      {
 530   4                                              // His FIN counts as a byte of data
 531   4                                              conxn[index].his_sequence++;
 532   4                                              tcp_send(&TCPSend,FLG_ACK, 20, index);
 533   4                                              conxn[index].state = STATE_CLOSE_WAIT;
 534   4      //                                      if (debug) PrintStr("TCP: Entered CLOSE_WAIT state\r");
 535   4      
 536   4                                      // At this point we would normally wait for the application
 537   4                                              // to close.  For now, send FIN immediately.
 538   4                                              tcp_send(&TCPSend,FLG_FIN | FLG_ACK, 20, index);
 539   4                                              conxn[index].my_sequence++;   // For my FIN
 540   4                                              conxn[index].state = STATE_LAST_ACK;
 541   4      //                                      if (debug) PrintStr("TCP: Entered LAST ACK state\r");
 542   4                                      }
 543   3                                      else if (data_len != 0)
 544   3                                      {
 545   4                                              //先判断对方的序列号是否小于conxn[index].his_sequence
 546   4                                              if(packSeq < conxn[index].his_sequence)
 547   4                                              {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -