2023/08/29 网络编程 day 3

基于UDP的tftp的传输协议

下载

#include 
#define PORT 69				//服务器端口号,范围1024-49151 
#define IP "192.168.114.161"  	//服务器IP,发给谁就填谁的IP
int do_download(int cfd,struct sockaddr_in sin);
int main(int argc, const char *argv[])
{
	//创建报式套接字文件
	int cfd;
	if((cfd = socket(AF_INET,SOCK_DGRAM,0))<0)
	{
		ERR_MSG("socket create error");
		return -1;
	}
	printf("socket create success cfd = %d\n",cfd);
	//填充绑定本机的地址信息
	struct sockaddr_in sin;
	sin.sin_family 			=AF_INET;
	sin.sin_port 			=htons(PORT);
	sin.sin_addr.s_addr 	=inet_addr(IP);
	char choose =0;

	//菜单
	while(1)
	{
		system("clear");
		printf("--------------------------------\n");
		printf("-----------1. 下载--------------\n");
		printf("-----------2. 上传--------------\n");
		printf("-----------3. 退出--------------\n");
		printf("--------------------------------\n");
		printf("请输入>>>>");
		scanf("%c",&choose);
		while(getchar()!=10);  //循环吸收垃圾字符
		int flag =1;
		switch(choose)
		{
		case '1':
			//下载
			do_download(cfd,sin);
			break;
		case '2':
			//上传
			//do_upload(cfd,sin);
			break;
		case '3':
			flag = 0;
			break;
		default:
			printf("输入错误,请重新输入");
			break;
		}
		if(flag == 0)
		{
			break;
		}
		printf("输入任意字符清屏>>>>\n");
		while(getchar()!=10);
	}
	//关闭套接字
	close(cfd);
	return 0;
}
int do_download(int cfd,struct sockaddr_in sin)
{
	char buf[516] ="";
	char filename[20]= "";
	printf("请输入要下载的文件名>>");
	scanf("%s",filename);
	while(getchar()!=10);
	//组下载请求包
	//操作码
	unsigned short *ptr1=(unsigned short *)buf;
	*ptr1 =htons(1);
	//文件名
	char *ptr2 = buf+2;
	strcpy(ptr2,filename);
	//模式
	char * ptr4 = ptr2 +strlen(filename)+1;
	strcpy(ptr4,"octet");
	//发送下载请求 sendto
	int size = 2+strlen(ptr2)+1+strlen(ptr4)+1;
	if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("sendto error");
		return -1;
	}
	printf("sendto download request  success\n");
	socklen_t addrlen = sizeof(sin);
	int fd;
	if((fd =open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664))== -1)
	{
		ERR_MSG("open error");
		return -1;
	}
	int res =0;
	while(1)
	{
		//接收数据recvfrom,接收地址信息
		if(( res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr *)&sin,&addrlen))<0)
		{
			ERR_MSG("recvfrom error");
			return -1;
		}	
		printf("%s\n",buf+4);
		//判断数据是否小于512字节,若小于则下载完成
		if(res<516)
		{
			write(fd,buf+4,res-4);
			break;
		}
		else if(res == 516)
		{
			write(fd,buf+4,512);
		}

		//组ACK包
		unsigned short *ptr1 = (unsigned short *)buf;
		*ptr1 = htons(4);
		//发送ACK sendto
		if(sendto(cfd,buf,4,0,(struct sockaddr *)&sin,sizeof(sin))<0)
		{
			ERR_MSG(sendto error);
			return -1;
		}
	}
	printf("下载完成\n");
}
int do_upload(int cfd,struct sockaddr_in sin)
{
	char buf[516] = "";
	int res =0;
	char filename[20] = "";
	printf("请输入要上传的文件名>>>");
	scanf("%s",filename);
	while(getchar()!=10);
	int fd;
	if((fd = open(filename,O_RDONLY))==-1)
	{
		ERR_MSG("open error");
		return -1;
	}
	//写请求
	//操作码
	unsigned short *ptr1 =(unsigned short *)buf;
	*ptr1 = htons(2);
	//文件名
	char *ptr2 = buf +2;
	strcpy(*ptr2,filename);
	//模式
	char ptr4 = ptr2+strlen(filename)+1;
	strcpy(*ptr4,"octet");
	int size =2+strlen(ptr2)+2+strlen(ptr4);
	//发送上传请求 sendto
	if(sendto(cfd,buf,size,0,(struct sockaddr *)&sin,sizeof(sin))<0)
	{
		ERR_MSG("sendto success");
		return -1;
	}
	printf("request success\n");
	int res;
	socklen_t addrlen = sizeof(sin);
	int blockNum = 0;
	while(1)
	{
		blockNum ++;
		//接收数据recvfrom,接收地址信息
		if((res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr *)&sin,&addrlen))<0)
		{
			ERR_MSG("recvfrom error");
			return -1;
		}
		//组数据包
		//操作码
		unsigned short *ptr1 =(unsigned short *)buf;
		*ptr1 =htons(3);
		unsigned short *ptr2 =(unsigned short *)(buf+2);
		*ptr2 = blockNum;
		
	}
}

你可能感兴趣的:(网络)