基于Linux的TFTP

TFTP概述

1.TFTP简单文件传送协议

2.最初用于引导无盘系统,被设计用来传输小文件

3.特点:

  1. 基于UDP协议实现
  2. 不进行用户有效性认证
4.数据传输模式:
  1. octet:二进制模式
  2. netascii:文本模式
  3.  mail:已经不再支持
5. TFTP通信过程总结

  1. 服务器在69号端口等待客户端的请求
  2. 服务器若批准此请求,则使用临时端口与客户端进行通信
  3. 每个数据包的编号都有变化(从1开始)
  4. 每个数据包都要得到ACK的确认如果出现超时,则需要重新发送最后的包(数据或ACK)
  5. 数据的长度以512Byte传输
  6. 小于512Byte的数据意味着传输结束

6.程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
	/*argv[1]:文件名,argv[2]:服务器IP地址*/
	//1创建UDP套接字
	int socket_client=socket(AF_INET,SOCK_DGRAM,0);
	if(socket_client<0)
	{
		perror("socket_client");
	}
	//2 标示目的信息
	struct sockaddr_in client_addr;//目的地址结构体,定义时使用
	bzero(&client_addr,sizeof(client_addr));
	client_addr.sin_family=AF_INET;//IP_4
	client_addr.sin_port=htons(69);// 服务器端口号,htos与数值处理有关
	client_addr.sin_addr.s_addr=inet_addr(argv[2]);//pc机端口号,innet_addr用于转换IP
//构造读请求数据包并发送到69端口

	char buf[250]="";
	int buf_len;
	buf_len=sprintf(buf,"%c%c%s%c%s%c",0,1,argv[1],0,"octet",0);
	sendto(socket_client,buf,buf_len,0,(struct sockaddr *)&client_addr,sizeof(client_addr));
//创建下载文件
	int fp = open(argv[1],O_RDWR|O_CREAT,0777);
	char recvbuf[1024]={0};
	char my_atk[4];
	int m_length;
	struct sockaddr_in from_addr;
	socklen_t len=sizeof(from_addr);
	while(m_length=recvfrom(socket_client,recvbuf,sizeof(recvbuf),0,(struct sockaddr *)&from_addr,&len)==516)
	{
		//判断数据操作码
		if(recvbuf[0]==0&&recvbuf[1]==3)//CMD=3(数据包)
		{
			//保存数据到文件
			write(fp,recvbuf+4,512); 
			//构造ACK包并发送到对方的临时端口
			my_atk[0]=0;
			my_atk[1]=4;
			my_atk[2]=recvbuf[2];
			my_atk[3]=recvbuf[3];
			sendto(socket_client,my_atk,4,0,(struct sockaddr *)&from_addr,sizeof(from_addr));
		}
		
	}
		//recvfrom(socket_client,recvbuf,strlen(recvbuf),0,(struct sockaddr *)&from_addr,&len);
		write(fp,recvbuf+4,512); 
		my_atk[0]=0;
		my_atk[1]=4;
		my_atk[2]=recvbuf[2];
		my_atk[3]=recvbuf[3];
		sendto(socket_client,my_atk,4,0,(struct sockaddr *)&from_addr,sizeof(from_addr));
		close(fp);
		close(socket_client);
		return 0;
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值