2024-03-17 作业

作业要求:

实现tftp功能:上传、下载

运行代码:

#include<myhead.h>
#define SER_PORT 69
#define SER_IP "192.168.1.101"
#define DOCU_SIZE 100
#define BUF_SIZE 516


void Prompt(int *app,char docu[]);
void tftp_app(int cfd,char buf[],char docu[],int app,struct sockaddr_in sin);//第一步申请
void download_data(int cfd,char buf[],char docu[],struct sockaddr_in sin);//第二步传输---下载
void upload_data(int cfd,char buf[],char docu[],struct sockaddr_in sin);//第二步传输---上传

void Prompt(int *app,char docu[])
{
	printf("****1.下载****\n");
	printf("****2.上传****\n");
	printf("****3.退出****\n");
	printf("你想干什么>>>");
	scanf("%d",app);
	if(*app==3){
		return;
	}
	printf("请输入文件名>>>");
	bzero(docu,DOCU_SIZE);
	scanf("%s",docu);
	while(getchar()!='\n');
}
/*********************请求*******************************/
void tftp_app(int cfd,char buf[],char docu[],int app,struct sockaddr_in sin)
{
	short int *p0 = (short int *)buf;
	*p0 = htons(app);//rd
	char *p1 = buf+2;//文件名
	strcpy(p1,docu);
	char *p2 = p1+strlen(p1)+1;
	strcpy(p2,"octet");
	int buf_size = 2+strlen(p1)+1+strlen(p2)+1;
	sendto(cfd,buf,BUF_SIZE,0,(struct sockaddr *)&sin,sizeof(sin));
	
}
/*********************下载******************************/
void download_data(int cfd,char buf[],char docu[],struct sockaddr_in sin)//第二步传输
{
	int wfp = open(docu,O_WRONLY|O_TRUNC|O_CREAT,0664);
	socklen_t addrlen = sizeof(sin);
	short int num=0;
	//发送ACK
	while(1){
		//接收信息
		bzero(buf,BUF_SIZE);
		int res=recvfrom(cfd,buf,BUF_SIZE,0,(struct sockaddr*)&sin,&addrlen);
		if(res<=0){
			break;
		}
		short int *p0 =(short int *)buf;
		short int num =*(p0+1);
		if(*p0!=htons(3)){
			printf("下载过程出错\n");
			printf("差错码>>>%d.差错信息>>>%s\n",htons(*((short int *)(buf+2))),buf+4);
			return;
		}
		write(wfp,buf+4,BUF_SIZE-4);
		//ACK发送
		bzero(buf,BUF_SIZE);
		short int *p_ack0=(short int *)buf;
		*p_ack0=htons(4);
		short int *p_ack1=p_ack0+1;
		*p_ack1=num;
		sendto(cfd,buf,4,0,(struct sockaddr *)&sin,sizeof(sin));
		//判断结束
		if(res<516){
			printf("下载结束\n");
			break;
		}
	}

	close(wfp);	
}
/***************************上传****************************/
void upload_data(int cfd,char buf[],char docu[],struct sockaddr_in sin)//第二步传输
{
	int rfp = open(docu,O_RDONLY);
	if(rfp == -1){
		perror("rfd");
		return;
	}
	socklen_t addrlen = sizeof(sin);
	short int num=1;
	//发送ACK
	while(1){
		//接收ACK
		bzero(buf,BUF_SIZE);
		recvfrom(cfd,buf,4,0,(struct sockaddr*)&sin,&addrlen);
		short int *p_ack0=(short int *)buf;
		//判断是否成功
		if(*p_ack0!=htons(4)){
			printf("上传失败\n");
			printf("差错码>>>%d.差错信息>>>%s\n",htons(*((short int *)(buf+2))),buf+4);

		}
		//发送信息
		bzero(buf,BUF_SIZE);
		//前四位设置
		short int *p0 =(short int *)buf;
		*p0 = htons(3);
		short int *p1 =p0+1;
		*p1 = htons(num++);
		//文件内容写入
		int res = read(rfp,buf+4,BUF_SIZE-4);
		sendto(cfd,buf,BUF_SIZE,0,(struct sockaddr *)&sin,sizeof(sin));
		//判断结束
		if(res<512){
			printf("下载结束\n");
			break;
		}
	}

	close(rfp);
}
int main(int argc, const char *argv[])
{
	//1.创建套接字文件
	int cfd = -1;
	if((cfd = socket(AF_INET,SOCK_DGRAM,0))==-1){
		perror("socket");
		return -1;
	}
	printf("%d success :cfd = %d\n",__LINE__,cfd);
 
	//信息交互
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	char buf[BUF_SIZE]={0};
	char docu[DOCU_SIZE]="2.png";
	int app=0;

#if 1
	while(1){
		Prompt(&app,docu);
		tftp_app(cfd,buf,docu,app,sin);
		switch(app){
		case 1:	download_data(cfd,buf,docu,sin);break;
		case 2: upload_data(cfd,buf,docu,sin);break;
		case 3: printf("正常退出\n");return 0;
		}
	}
#endif
	//关闭文件
	close(cfd);
	return 0;
}

运行截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值