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

📄 tcp.lst

📁 RTL8019以太网开发板资料
💻 LST
字号:
C51 COMPILER V8.18   TCP                                                                   06/19/2010 21:01:39 PAGE 1   


C51 COMPILER V8.18, COMPILATION OF MODULE TCP
OBJECT MODULE PLACED IN TCP.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE TCP.C LARGE BROWSE DEBUG OBJECTEXTEND

line level    source

   1          //-----------------------------------------------------------------------------
   2          // Net TCP.C
   3          //
   4          // This module handles TCP segments
   5          // Refer to RFC 793, 896, 1122, 1323, 2018, 2581
   6          //
   7          // A "connection" is a unique combination of 4 items:  His IP address,
   8          // his port number, my IP address, and my port number.
   9          //
  10          // Note that a SYN and a FIN count as a byte of data, but a RST does
  11          // not count. Neither do any of the other flags.
  12          // See "TCP/IP Illustrated, Volume 1" Sect 17.3 for info on flags
  13          //-----------------------------------------------------------------------------
  14          #include <string.h>
  15          #include <stdlib.h>
  16          #include <ctype.h>              // toupper
  17          #include "main.h"               // toupper
  18          #include "udp.h"                // toupper
  19          #include "rs232.h"              // toupper
  20          #include "tcp.h"                // toupper
  21          #include "ip.h"         // toupper
  22          #include "ARP.h"                // toupper
  23          
  24          // These structures keep track of connection information
  25          Str_CONNECTION xdata StrConnection_buf[5];        //设置可以同时接收5组IP地址的TCP数据
  26          UWORK32 initial_sequence_nr;
  27          UWORK8 TcpStateFlag;                            //TCP的状态标志位,是在各个过程中的状态 
  28          char xdata text[];
  29          // Options: MSS (4 bytes), NOPS (2 bytes), Selective ACK (2 bytes) 
  30          UWORK8 code options_buf[10] = {0x02, 0x04, 0x05, 0xB4, 0x01, 0x01, 0x04, 0x02};
  31          UWORK8 code optionsRe_buf[4] = {0x02, 0x04, 0x05, 0x78};          //建立连接的TCP选项
  32          
  33          UWORK8 HttpSendFlag;            //TCP有发送的数据
  34          
  35          //------------------------------------------------------------------------
  36          //  Initialize variables declared in this module
  37          //
  38          //------------------------------------------------------------------------
  39          void init_tcp(void)
  40          {
  41   1         memset(StrConnection_buf, 0, sizeof(StrConnection_buf));
  42   1         initial_sequence_nr = 1;
  43   1      }
  44          //------------------------------------------------------------------------
  45          // This runs every 0.5 seconds.  If the connection has had no activity
  46          // it initiates closing the connection.
  47          //
  48          //------------------------------------------------------------------------
  49          
  50          void tcp_inactivity(void)
  51          {
  52   1         UWORK8 idata nr;
  53   1         
  54   1         // Look for active connections in the established state
  55   1         for (nr = 0; nr < 5; nr++)
C51 COMPILER V8.18   TCP                                                                   06/19/2010 21:01:39 PAGE 2   

  56   1         {
  57   2            if ((StrConnection_buf[nr].ipaddr != 0) && (StrConnection_buf[nr].state == STATE_ESTABLISHED) && (St
             -rConnection_buf[nr].inactivity))
  58   2            {
  59   3               // Decrement the timer and see if it hit 0
  60   3               StrConnection_buf[nr].inactivity--;
  61   3               if (StrConnection_buf[nr].inactivity == 0)
  62   3               {
  63   4                  // Inactivity timer has just timed out.
  64   4                  // Initiate close of connection
  65   4                  tcp_ReBack((FLG_ACK | FLG_FIN), 20, nr);
  66   4                  StrConnection_buf[nr].state = STATE_FIN_WAIT_1;
  67   4               }
  68   3            }
  69   2         }
  70   1      }
  71          
  72          
  73          //------------------------------------------------------------------------
  74          // This runs every 0.5 seconds.  If the other end has not ACK'd
  75          // everyting we have sent, it re-sends it.  To save RAM space, we 
  76          // regenerate a segment rather than keeping a bunch of segments 
  77          // hanging around eating up RAM.  A connection should not be in an
  78          // opening or closing state when this timer expires, so we simply
  79          // send a reset.
  80          //
  81          //      If a connection is in the ESTABLISHED state when the timer expires
  82          // then we have just sent a web page so re-send the page
  83          //------------------------------------------------------------------------
  84          
  85          void tcp_retransmit(void)
  86          {
  87   1         UWORK8 nr;
  88   1         // Scan through all active connections 
  89   1         for (nr = 0; nr < 5; nr++)
  90   1         {
  91   2            if ((StrConnection_buf[nr].ipaddr != 0) && (StrConnection_buf[nr].timer) && (StrConnection_buf[nr].R
             -eSendNum != 0))
  92   2            {
  93   3               // Decrement the timer and see if it hit 0
  94   3               StrConnection_buf[nr].timer--;
  95   3               if (StrConnection_buf[nr].timer == 0)
  96   3               {
  97   4                       StrConnection_buf[nr].ReSendNum--;
  98   4                              // Socket just timed out. If we are not in ESTABLISHED state
  99   4                  // something is amiss so send reset and close connection
 100   4                  if (StrConnection_buf[nr].state != STATE_ESTABLISHED)
 101   4                  {
 102   5                     tcp_ReBack(FLG_RST, 20, nr);              // Send reset and close connection
 103   5                     StrConnection_buf[nr].ipaddr = 0;
 104   5                     return;
 105   5                  }
 106   4                  else
 107   4                  {
 108   5                                      StrConnection_buf[nr].ucSERIESNUM = StrConnection_buf[nr].ucRESERIESNUM; 
 109   5                                 switch(StrConnection_buf[nr].HttpFlag)
 110   5                                 {
 111   6                                              case TCP_COM:            //重复发送TCP命令
 112   6                                                      tcp_ReSendBack(StrConnection_buf[nr].SendLen, nr);
 113   6                                                      break;
 114   6                                              case TCP_TDATA:         //重复发送数据
 115   6                                                      tcp_ReSend(StrConnection_buf[nr].SendLen, nr);
C51 COMPILER V8.18   TCP                                                                   06/19/2010 21:01:39 PAGE 3   

 116   6                                                      break;
 117   6                                              case TCP_HTTP:
 118   6                                                      break;
 119   6                                              default:
 120   6                                                      break;
 121   6                      }
 122   5                  }
 123   4                              if(StrConnection_buf[nr].ReSendNum == 0)
 124   4                              {
 125   5                          StrConnection_buf[nr].inactivity = INACTIVITY_TIME;            //转入下一级15秒定时
 126   5                              }
 127   4               }
 128   3            }
 129   2         }
 130   1      }
 131          
 132          
 133          /*********************************************************************
 134          函数名:       void IpReceive(void)
 135          功能:         Ip处理,因为是接收一帧处理一帧,不用返回成功失败
 136          输入:         接收的帧是Ip帧 
 137          输出:         处理IP分组
 138          返回:         None
 139          日期:         2004/12/20
 140          *********************************************************************/
 141          UWORK16 cksum(UWORK8 xdata *check,UWORK16 length) //计算校验和
 142          {
 143   1              UWORK32 sum=0;
 144   1              UWORK16 i;
 145   1              UWORK16 xdata *ptr; 
 146   1          ptr=(UWORK16 xdata *)check;
 147   1              for (i=0;i<(length)/2;i++)
 148   1              {
 149   2                      sum+=*ptr++;
 150   2              }
 151   1              if (length&0x01)//表示长度为单数
 152   1              {
 153   2                      sum=sum+((*ptr)&0xff00);
 154   2              }
 155   1              sum=(sum&0xffff)+((sum>>16)&0xffff);//高16位和低16位相加
 156   1              if(sum&0xffff0000)
 157   1              {//表示有进位
 158   2                      sum++;
 159   2              }
 160   1              return ( (UWORK16)((sum)&0xffff));
 161   1      //      return ( (UWORK16)(~((sum)&0xffff)));
 162   1      }
 163          
 164          /*********************************************************************
 165          函数名:       void tcp_ReBack(UWORK16 flags,  UWORK16 hdr_len, UWORK8 nr)
 166          功能:         发送TCP
 167          输入:        flags: TCP的标志位, hdr_len: TCP的长度,nr:是接收的次数  
 168          输出:         None
 169          返回:         None
 170          日期:         2004/02/04
 171          *********************************************************************/
 172          void tcp_ReBack(UWORK16 flags,  UWORK16 TCPHead_len, UWORK8 nr)
 173          {
 174   1         ST_TCP_FORMAT *strTcp;
 175   1         UWORK8 destIP_buf[4];
 176   1      
 177   1          strTcp = (ST_TCP_FORMAT *)&NetSend_buf[20];
C51 COMPILER V8.18   TCP                                                                   06/19/2010 21:01:39 PAGE 4   

 178   1      
 179   1          strTcp->usSourcePort = SourcePort;                          //源端口
 180   1          strTcp->usDesPort = DesPort;                        //目标端口,在接收TCP时已附值
 181   1              strTcp->ucSERIESNUM = StrConnection_buf[nr].ucSERIESNUM;         //序号为0
 182   1              strTcp->ucTRUECODE = StrConnection_buf[nr].ucTRUECODE;   //确认号为0
 183   1              memcpy(destIP_buf,(UWORK8 *)&StrConnection_buf[nr].ipaddr, 4);  //发送的目标IP地址在TCP接收中已附值
 184   1      
 185   1         strTcp->ucMOVENUM = (TCPHead_len << 10) | flags;               //记算TCP的头长度及相关的标志位
 186   1         strTcp->ucWINDOWBIG = 1024;                                            //设置窗口大小
 187   1         strTcp->ucTCPCHECK = 0;                                                        //先设置校验位为0
 188   1         strTcp->ucMUSGPOINT = 0;                                                       //紧急指针为0
 189   1         
 190   1         if (TCPHead_len == 24)                                                          //建立连接是的TCP的选项
 191   1         {
 192   2            memcpy(&strTcp->options[0], optionsRe_buf, 4);               //把默认的TCP选择附值过去
 193   2         } 
 194   1         else if (TCPHead_len == 28)                                                     //如果发送的字节为28,那么多余的部分为TCP的很选项
 195   1         {
 196   2            memcpy(&strTcp->options[0], options_buf, 8);                 //把默认的TCP选择附值过去
 197   2         } 
 198   1         //下面是给IP打包头
 199   1          gstIphead.ucVerAndLen = 0x45;                       //版本号和长度,各占4位
 200   1          gstIphead.ucDs = 0;                        //区分服务
 201   1          gstIphead.usTotalLen = IP_HEAD_LEN + TCPHead_len;                        //头加后面的数据
 202   1          gstIphead.usID = ++LocalIpID;
 203   1          gstIphead.usSegOffset = 0;
 204   1      
 205   1          gstIphead.ucTTL = 0;                                                                                 // max hops
 206   1          gstIphead.ucprotocol = TCP;
 207   1          gstIphead.usCheckSum = TCPHead_len;                                   //在计算TCP的校验位时,TCP的长度
             -要算两次,此时是借IP的校验位来做第二个TCP的长度
 208   1          memcpy(&gstIphead.ucDestIP[0],&IPDestAddress_buf[0],IP_LEN);          // 目的IP 
 209   1          memcpy(&gstIphead.ucSourceIP[0],&IPLocalAddress_buf[0],IP_LEN);                // 源IP    
 210   1          memcpy(&NetSend_buf[0],&gstIphead,20);                                                                                //把IP的头传给发送缓存区
 211   1              strTcp->ucTCPCHECK = 0;
 212   1              strTcp->ucTCPCHECK = CheckSum((UWORK16 *)&NetSend_buf[8],TCPHead_len + 12);   // 20 = 12个字节伪头 + 8个

⌨️ 快捷键说明

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