📄 tcp.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 + -