day3

基于UDP的TFTP文件传输

//主函数
#include "head.h"
int main(int argc, const char *argv[])
{
	//创建报式套接字
	int cli_fd;
	cli_fd = socket(AF_INET,SOCK_DGRAM,0);
	if(cli_fd<0)
	{
		ERR_MSG("socket");
		return -1;
	}
	//准备发送对象的信息地址结构体
	struct sockaddr_in ser_sin;
	ser_sin.sin_family = AF_INET;
	ser_sin.sin_port = htons(PORT);
	ser_sin.sin_addr.s_addr = inet_addr(IP);
	//下载
	if(DownLoad(cli_fd,ser_sin)<0)
	{
		printf("DownLoad failed\n");
	}
	//关闭套接字流指针
	close(cli_fd);
	return 0;
}

//头文件
#ifndef __HEAD_HH__
#define __HEAD_HH__
#include <quick.h>
#define PORT 69
#define IP "192.168.1.8"
int DownLoad(int cli_fd,struct sockaddr_in ser_sin);
#endif

//子函数
#include "head.h"

//下载
#include "head.h"
//下载
int DownLoad(int cli_fd,struct sockaddr_in ser_sin)
{
	//从终端中获取下载文件名
	printf("please enter a filename : ");
	char filename[128]="";
	fgets(filename,sizeof(filename),stdin);
	filename[strlen(filename)-1]=0;
	//以写的方式打开文件
	int fd_w = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664);
	if(fd_w<0)
	{
		perror("open");
		return -1;
	}
	printf("file has been opened\n");
	//创建地址信息结构体,用来存放服务器临时地址信息
	struct sockaddr_in tem_sin;
	socklen_t addrlen;
	//包装读写请求字符串
	char readask[128]="";
	short *rp1=(short *)readask;
	*rp1 = htons(1);
	char *rp2=readask+2;
	strcpy(rp2,filename);
	char *rp3=rp2+strlen(filename)+1;
	strcpy(rp3,"octet");
	//变量
	char dload[516]="";
	ssize_t res=0;
	size_t len=4+strlen(rp2)+strlen(rp3);
	//发送读写请求
	res = sendto(cli_fd,readask,len,0,(struct sockaddr*)&ser_sin,sizeof(ser_sin));
	if(res<0)
	{
		printf("send ask to server failed\n");
		return -1;
	}
	printf("read ask sended\n");
	while(1)
	{
		//接收数据包
		bzero(dload,sizeof(dload));
		res = recvfrom(cli_fd,dload,sizeof(dload),0,(struct sockaddr *)&tem_sin,&addrlen);
		if(res<0)
		{
			printf("receive failed\n");
			return -1;
		}
		printf("receive finished\n");
		//解析数据,包括临时地址信息
		//*dload = ntohs(*dload);
		short *wp1 = (short *)dload;
		*wp1 = ntohs(*wp1);
		short *wp2 = wp1+1;
		*wp2 = ntohs(*wp2);
		char *wp3 = dload+4;
		//包装ACK返回信息字符串
		char ack[4]="";
		short *ap1 = (short *)ack;
		*ap1 = htons(4);
		short *ap2 = ap1+1;
		*ap2 = htons(*wp2);
		//返回ACK读取信息完毕信息
		if(sendto(cli_fd,ack,4,0,(struct sockaddr*)&tem_sin,sizeof(ser_sin))<0)
		{
			printf("send ACK to server failed\n");
			return -1;
		}
		printf("ACK sended\n");
		//将读取的数据写入文件中
		write(fd_w,wp3,res-4);
		//判断是否读取完毕
		printf("res = %ld\n",res);
		if(res < 516)
		{
			printf("DownLoad finished\n");
			break;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值