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

📄 tcp.c

📁 ppp拨号程序源代码采用atmel芯片c语言编
💻 C
📖 第 1 页 / 共 4 页
字号:

		switch (Socket->Stage)
		{
			case TCP_LISTEN			:	return;
			case TCP_SYN_SENT		:	Socket->Flags |= TCP_FIN;
			case TCP_SYN_RECEIVED	:	TCP_SocketStage(Socket, TCP_CLOSE_WAIT);
										break;
			case TCP_ESTABLISHED	:	TCP_SocketStage(Socket, TCP_CLOSE_WAIT);
										break;
			case TCP_FIN_WAIT_1		:	TCP_SocketStage(Socket, TCP_FIN_WAIT_2);
										break;
			case TCP_FIN_WAIT_2		:	TCP_SocketStage(Socket, TCP_TIME_WAIT);
										u16_Put(&Socket->Retry_Timer, 0);
										break;
			case TCP_CLOSE_WAIT		:
			case TCP_CLOSING		:
			case TCP_LAST_ACK		:
			case TCP_TIME_WAIT		:	TCP_SocketStage(Socket, TCP_TIME_WAIT);
										break;
			default					:	TCP_SocketStage(Socket, TCP_CLOSED);
										return;
		}

		Socket->TheirSequenceNum = ntohl(TCP_Header->SequenceNum) + 1;				// their sequence number
		Socket->Flags |= TCP_ACK;													// we need to send an ACK back
	}

	// *******************
	// ack

	if (TCP_Header->ControlBits & TCP_ACK)
	{	// ACK
		switch (Socket->Stage)
		{
			case TCP_LISTEN			:	return;
			case TCP_SYN_SENT		:	TCP_SendPacket(Socket, TCP_RST);		// send a packet back
										TCP_SocketStage(Socket, TCP_CLOSED);
										return;
			case TCP_SYN_RECEIVED	:	// we were waiting for the ack
										TCP_UpdateRoundTripTime(Socket, u16_Get(&Socket->Retry_Timer));

										Socket->OurSequenceNum++;
										TCP_SocketStage(Socket, TCP_ESTABLISHED);

										if (!Socket->OutGoing)
										{
											strcpy(ScratchPad, "z8 Tcp server\r\n--------------\r\n");
											TCP_TxData(Socket, ScratchPad, strlen((char*)ScratchPad));	// send them some text
										}
										break;
			case TCP_ESTABLISHED	:	if (Socket->OurSequenceNum != ntohl(TCP_Header->AckNum))
										{	// ack to some data we have sent
											TCP_UpdateRoundTripTime(Socket, u16_Get(&Socket->Retry_Timer));

											dw = ntohl(TCP_Header->AckNum);
											if (dw < Socket->OurSequenceNum)
												dw += 1 + (0xffffffff - Socket->OurSequenceNum);	// 32-bit unsigned rap-around number
											else
												dw -= Socket->OurSequenceNum;
											if (dw > Socket->OurLastBytesSent) dw = Socket->OurLastBytesSent;	// hmmm

											Socket->TxBufferRd += (s16)dw;
											while (Socket->TxBufferRd >= sizeof(Socket->TxBuffer)) Socket->TxBufferRd -= sizeof(Socket->TxBuffer);

											Socket->OurSequenceNum += dw;
											Socket->OurLastBytesSent = 0;

											Socket->Retries = 0;
											u16_Put(&Socket->Retry_Timer, Socket->RoundTripTime * TCP_Retry_Time);	// next packet asap
										}
										break;
			case TCP_FIN_WAIT_1		:	TCP_UpdateRoundTripTime(Socket, u16_Get(&Socket->Retry_Timer));

										TCP_SocketStage(Socket, TCP_FIN_WAIT_2);				// we got an ack back for the FIN we sent
										break;
			case TCP_FIN_WAIT_2		:	TCP_SocketStage(Socket, TCP_TIME_WAIT);
										break;
			case TCP_CLOSE_WAIT		:	break;
			case TCP_CLOSING		:	TCP_SocketStage(Socket, TCP_TIME_WAIT);
										break;
			case TCP_LAST_ACK		:	TCP_SocketStage(Socket, TCP_CLOSED);
			case TCP_TIME_WAIT		:	break;
			default					:	break;
		}

		if (TCP_Header->ControlBits & TCP_URG)											//
		{																				//
		    if (TCP_Header->UrgentPointer)												//
		    {																			//
//				dw = ntohl(TCP_Header->SequenceNum);									//
//            	dw += (u32)ntohs(TCP_Header->UrgentPointer);							// dw = the sequence number of this data
				Socket->Flags |= TCP_ACK;												// send an ACK back
   				goto SendNow;															// we don't yet deal with urgent pointers :(
 			}																			//
	    }																				//
																						//
		if (ntohl(TCP_Header->SequenceNum) == Socket->TheirSequenceNum)						//
		{																						//
			if (len) i = TCP_RxSaveData(Socket, MainBuffer + MainBufferRd_Rx, (int)len);		// save the data sent in the packet into our rx buffer and sent ask back
		}																						//
		else																					//
			Socket->Flags |= TCP_ACK;															// tell them seq-num we were expecting
	}

	// *******************
	// Send any packets back that need sending

SendNow:    
	if (Socket->Flags)
	{
		TCP_SendPacket(Socket, Socket->Flags);											// send a packet back
	}

	return;

	// *******************
	// reject the packet completely

RefuseConnection:																			//
//		if (IP_FireWalled())																//
//		{																					//
//			#ifdef Debug																	//
//				SendDebugRStr(tcp_str21);													//
//			#endif																			//
//			return;																			// firewalled - just don't bother with them
//		}																					//

	if (TCP_Header->ControlBits & TCP_RST) return;											// we don't send RST in responce to RST rx'ed
    																						//																							//
	// swap the packet round and send it back												//
																							//
	dw = IP_Header->DestIP.ip32;															//
	IP_Header->DestIP.ip32 = IP_Header->SourceIP.ip32;										//
	IP_Header->SourceIP.ip32 = dw;															//
																							//
	len = TCP_Header->SourcePort;															//
	TCP_Header->SourcePort = TCP_Header->DestPort;											//
	TCP_Header->DestPort = len;																//
																							//
	dw = TCP_Header->SequenceNum;															//
	TCP_Header->SequenceNum = TCP_Header->AckNum;											//
	TCP_Header->AckNum = dw;																//
																							//
	TCP_Header->DataOffset = sizeof(T_TCP_Header) >> 2;										//
	TCP_Header->DataOffset <<= 4;															//
																							//
	TCP_Header->ControlBits = TCP_RST | TCP_ACK;											// set the tx packet control bits
																							//
	TCP_Header->Checksum = 0;																//
	TCP_Header->WindowSize = 0;																//
	TCP_Header->UrgentPointer = 0;															//
																							//
	MainBufferWr_Tx = sizeof(T_PPP_Header1) + sizeof(T_IP_Header) + sizeof(T_TCP_Header);	// update index
																							//
	len = IP_Checksum2((char*)TCP_Header, sizeof(T_TCP_Header));							// update the TCP header checksum
//	if (!len) len = 0xffff;																	//
	TCP_Header->Checksum = htons(len);														//
																							//
	IP_Header->ID = htons(IP_ID++);															//
	IP_Header->Checksum = 0;																// update the IP header
	IP_Header->TotalLength = sizeof(T_IP_Header) + sizeof(T_TCP_Header);					// update the IP header
	IP_Header->TotalLength = htons(IP_Header->TotalLength);									//
																							//
	len = (u16)(IP_Header->VerLen & 0x0f);													// number of 32-bit words to the ip header
	len <<= 2;																				// now number of bytes
	len = IP_Checksum1((char*)IP_Header, len);												// update the IP header checksum
//	if (!len) len = 0xffff;																	//
	IP_Header->Checksum = htons(len);														//
																							//
	len = MainBufferWr_Tx;																	//
																							//
	if (!PPP_SendPacket(false)) return;														// send it

	#ifdef Debug
		IP_DisplayProtocol(true, (int)len);													//
		IP_DisplayHeader(sizeof(T_PPP_Header1), (int)len);									//
		TCP_DisplayHeader(sizeof(T_PPP_Header1) + sizeof(T_IP_Header), (int)len);			//
	#endif

	return;
}

// ******************************************************************************************
// this is called from the ip module - every 10ms

void TCP_10ms_Timer(void)
{
	u16				w;
	T_TCP_Socket	*Socket;

	Socket = TCP_Socket;														// we only have the one - for now
	if (Socket == NULL) return;													// no socket to update
																				//
	if (Socket->Stage == TCP_ESTABLISHED)										//
	{																			//
		if (Socket->ConnectTime < 4294967195) Socket->ConnectTime += 10;		//
		if (Socket->LastRxData < 4294967195) Socket->LastRxData += 10;		//
																				//
		if (Socket->AckDelay < 65000)											//
		{																		//
			w = Socket->AckDelay + 10;											//
			if ((Socket->AckDelay < TCP_AckDelay) && (w >= TCP_AckDelay)) Socket->SendAck = true;	// time to send ack back
			Socket->AckDelay = w;												//
		}																		//
	}																			//
																				//
	if ((Socket->Stage == TCP_CLOSED) || (Socket->Stage == TCP_LISTEN)) return;	//
																				//
	if (Socket->Retry_Timer < 65000) Socket->Retry_Timer += 10;					// ms since last packet sent
}

// ******************************************************************************************
// this is called from the ip module
// - it takes care of the TCP link for you

void TCP_Process(void)
{
	T_TCP_Socket	*Socket;

	Socket = TCP_Socket;								// we only have the one - for now
	if (Socket == NULL) return;							// no socket to update
														//
	if (Socket->Stage == TCP_CLOSED)					//
	{													//
		#ifndef StaticTCPSocket
			realloc(Socket, 0);							// free the socket memory
			Socket = 0;									//
		#endif

		Socket = TCP_SocketListen(TCP_Port);			// re-open it for listening
		return;											//
	}													//

	if (Socket->Stage == TCP_LISTEN) return;			// waiting for an incoming connection

	if (Socket->Stage == TCP_ESTABLISHED)											//
	{																				//
		if ((TCP_DataTimeOut) && (u32_Get(&Socket->LastRxData) >= TCP_DataTimeOut))	// tcp no-data timeout
		{																			// disconnect
			TCP_CloseSocket(Socket);												//
			return;																	//
		}																			//
	}																				//

	if (u16_Get(&Socket->Retry_Timer) < (Socket->RoundTripTime * TCP_Retry_Time)) return;	// not time to retry a packet send

	if (Socket->Retries >= TCP_Retries)					//
	{													// give up with the link
		TCP_SocketStage(Socket, TCP_CLOSED);			//
		TCP_SendPacket(Socket, TCP_ACK | TCP_RST);		//
		return;											//
	}													//
														//
	if (MainBufferWr_Rx > 0) return;					// something else is using the buffer atm
	if (MainBufferWr_Tx > 0) return;					//   " 

	switch (Socket->Stage)
	{
		case TCP_CLOSED			:	break;
		case TCP_LISTEN			:	break;
		case TCP_SYN_SENT		:
		case TCP_SYN_RECEIVED	:	TCP_SendPacket(Socket, TCP_SYN);
									break;
		case TCP_ESTABLISHED	:	// send any data that needs sending
									if (Socket->TxBufferRd != Socket->TxBufferWr) TCP_SendPacket(Socket, TCP_ACK | TCP_PSH);	// send some data
									else																						//
									if (Socket->SendAck) TCP_SendPacket(Socket, TCP_ACK);										// send ack back
									break;
		case TCP_FIN_WAIT_1		:	TCP_SendPacket(Socket, TCP_FIN | TCP_ACK);
									break;
		case TCP_FIN_WAIT_2		:	// waiting for their FIN packet
									break;
		case TCP_CLOSE_WAIT		:	TCP_SendPacket(Socket, TCP_FIN | TCP_ACK);
									TCP_SocketStage(Socket, TCP_LAST_ACK);
									u16_Put(&Socket->Retry_Timer, 0);
									break;
		case TCP_CLOSING		:
									break;
		case TCP_LAST_ACK		:	TCP_SendPacket(Socket, TCP_FIN | TCP_ACK);
									break;
		case TCP_TIME_WAIT		:	TCP_SocketStage(Socket, TCP_CLOSED);
									break;
		default					:	TCP_SocketStage(Socket, TCP_CLOSED);
									break;
	}
}

// ******************************************************************************************

⌨️ 快捷键说明

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