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

📄 tftpclient.c.txt

📁 linux下的tftp源代码,分为服务器端和连接客户端
💻 TXT
字号:
#include "tftpclient.h"

struct CONTEXT Context;

int main(int argc, char* argv[])
{	
	int sock;	
	struct sockaddr_in ServAddr;
	struct sockaddr_in RemoteAddr;
//	struct in_addr *clientaddr;
	unsigned int RemoteAddrLen;
	unsigned short *opcode;
	int ret=0;
	unsigned char msg[600], sendmsg[600];
	int msgsize, sendsize;
	struct RRQ *rrqpacket;
	char filename[80];
	FILE *fp;

	if(argc != 4)
	{
		printf("\nUsage: %s ip_addr ip_port [r|w]", argv[0]);
		exit(0);
	}
	
	if((sock=socket(PF_INET, SOCK_DGRAM, 0))<0)
	{
		printf("\n Error : socket() failed");
		exit(-1);
	}
	memset(&ServAddr, 0, sizeof(ServAddr));
	ServAddr.sin_family = AF_INET;	
	ServAddr.sin_addr.s_addr = inet_addr(argv[1]);
	ServAddr.sin_port = htons(atoi(argv[2]));

	if(argv[3][0] == 'r')
	{
		printf("\n  Input the file name: ");
		scanf("%s", filename); 
		rrqpacket = (struct RRQ *)sendmsg;
		rrqpacket->OpCode = htons(RRQ_OPCODE);
		strcpy(rrqpacket->FileName, filename);
		strcpy(rrqpacket->Mode, BIN);

		if((fp = fopen(filename, "w+b"))==NULL)
		{
			printf("\n Error : Cannot open for write");
			exit(-1);
		}

		if( (sendsize = sendto(sock, sendmsg, sizeof(struct RRQ), 0, 
			(struct sockaddr*)&ServAddr, sizeof(ServAddr))) < 0 )
		{
			printf("\n Error : sendto() failed !!");
			exit(-1);
		}

		printf("\n Send RRQ[%d]\n", sendsize);

		memset(&Context, 0, sizeof(struct CONTEXT));
		Context.State = RECV_DATA_STATE;
		Context.RecvNumber = 1;
		strcpy(Context.FileName, filename);
		Context.fp=fp;

	}
	else if(argv[3][0] == 'w')
	{
		printf("\n  Sorry ..   Not implemented yet .");
		exit(0);
	}
	else 
	{
		printf("\n Unknown operation %s\n", argv[3]);
		exit(0);
	}

	for(;;)
	{
		RemoteAddrLen = sizeof(RemoteAddr);
		memset(msg, 0, sizeof(msg));
		if( (msgsize = recvfrom(sock, msg, 600, 0, (struct sockaddr*)&RemoteAddr, 
			&RemoteAddrLen) ) < 0 )
		{
			printf("\n Error : recvfrom() failed !!\n");
			exit(-1);
		}
		opcode = (unsigned short*)msg;
		switch(ntohs(*opcode))
		{
			case DATA_OPCODE :
				printf("\n Recv DATA msg[%d]\n", msgsize);
				ret = process_DATA(sock, msg, msgsize, &RemoteAddr, RemoteAddrLen);
				break;
			case ACK_OPCODE :
				ret = process_ACK(sock, msg, msgsize, &RemoteAddr, RemoteAddrLen);
				break;
			case ERROR_OPCODE :
				printf("\n Recv ERROR msg[%d]\n", msgsize);
				ret = process_ERROR(sock, msg, msgsize, &RemoteAddr, RemoteAddrLen);
				break;
			default :
				printf("\n ERROR :  Receive Unknown OpCode[%u] Packet !! -> Ignore\n ", 
					ntohs(*opcode));
				ret=-1;
		}
		if(ret <= 0)
		{
			close(sock);
			return 0;
		}

	}
	return 0;
}

int process_DATA(int socket, char *msg, int recvsize, 
		struct sockaddr_in *remoteaddr, int remoteaddrsize)
{
	FILE *fp;
	struct DATA	*datapacket;
	struct ACK *ackpacket;
	char sendmsg[600];
	int writesize;
	int sendsize;
	
	if( recvsize < sizeof(struct DATA))
	{
		printf("\n Error : Bad DATA size: %d ", recvsize);
		send_error(socket, remoteaddr, remoteaddrsize, 0, "Bad Packet Size");
		return -1;
	}
	if( Context.State != RECV_DATA_STATE )
	{
		printf("\n Error : DATA but Bad state: %d ", Context.State);
		send_error(socket, remoteaddr, remoteaddrsize, 0, "recv DATA but Bad state");
		return -1;
	}

	datapacket = (struct DATA *)msg;
	if( ntohs(datapacket->BlockNumber) != Context.RecvNumber)
	{
		printf("\n Error : DATA but error blocknumber %d  Context.recvnumber %d", 
			ntohs(datapacket->BlockNumber), Context.RecvNumber);
		send_error(socket, remoteaddr, remoteaddrsize, 0, "DATA but error blocknumber");
		return 1;
	}
	writesize = recvsize-sizeof(struct DATA)+1;
	printf("\n Write File [%d ~ %d] bytes", Context.CurrentByteSize, 
		Context.CurrentByteSize+writesize-1);
	
	fwrite(datapacket->Data, 1, writesize, Context.fp);
	
	ackpacket=(struct ACK *)sendmsg;
	ackpacket->OpCode = htons(ACK_OPCODE);
	ackpacket->BlockNumber= htons(Context.RecvNumber);
	
	Context.RecvNumber++;
	Context.CurrentByteSize += writesize;

	if(writesize < 512)
	{
		printf("\n Receive All data ..\n");
		fclose(Context.fp);
		sendsize= sendto(socket, ackpacket, sizeof(struct ACK), 0, 
			(struct sockaddr*)remoteaddr, remoteaddrsize);		
		printf("\n Send LAST ACK[%d] Blocknum[%u] \n", sendsize, ntohs(ackpacket->BlockNumber));
		return 0;  // end of processing ..
	}

	sendsize=sendto(socket, ackpacket, sizeof(struct ACK), 0, (struct sockaddr*)remoteaddr, 
		remoteaddrsize);
	printf("\n Send ACK[%d]  Blocknum[%u] \n", sendsize, ntohs(ackpacket->BlockNumber));
	return 1;  // further processing required

}

int process_ACK(int socket, char *msg, int recvsize, 
		struct sockaddr_in *remoteaddr, int remoteaddrsize)
{
	printf("\n Not Implemented yet.. ");
	return 1;
}

int process_ERROR(int socket, char *msg, int recvsize, 
		struct sockaddr_in *remoteaddr, int remoteaddrsize)
{
	struct ERROR *errorpacket;

	if( recvsize < sizeof(struct ERROR))
	{
		printf("\n Error Packet : Bad ERROR size: %d ", recvsize);
		return -1;
	}
	errorpacket = (struct ERROR *)msg;

	printf("\n ERROR packet recv  ErrorNumber: %u  ErrorMsg : %s", 
		ntohs(errorpacket->OpCode), errorpacket->ErrorData);

	return -1;
}

int send_error(int socket, struct sockaddr_in *remoteaddr, int remoteaddrsize, 
			unsigned short errorcode, char *errormsg)
{
	char sendmsg[128];
	struct ERROR *errorpacket;

	errorpacket = (struct ERROR *)sendmsg;
	errorpacket->OpCode = htons(ERROR_OPCODE);
	errorpacket->ErrorNumber = htons(errorcode); // file not found ..
	strcpy(errorpacket->ErrorData, errormsg);

	if (sendto(socket, &errorpacket, sizeof(struct ERROR),0,
		(struct sockaddr*)remoteaddr, remoteaddrsize) < 0)
	{
		printf("\n Error : Error Packet Send failed() ");
		return -1;
	}
	return 1;
}


⌨️ 快捷键说明

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