嵌入式学习-网络编程-Day4

发布时间:2024年01月17日

嵌入式学习-网络编程-Day4

一、思维导图

在这里插入图片描述

二、作业

1.

#include <myhead.h>
//下载函数
int download_file(int cfd,struct sockaddr_in sin);
//上传函数
int updown_file(int cfd,struct sockaddr_in sin);
int main(int argc, const char *argv[])
{
	//创建用于通信的套接字文件描述符
	int cfd=-1;
	if((cfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
	{
		perror("socket error");
		return -1;
	}

	//填充服务器的地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(69);
	sin.sin_addr.s_addr=inet_addr("192.168.122.120");

	int menu;
	while(1)
	{
		printf("\t\t=====1、上传=====\n");
		printf("\t\t=====2、下载=====\n");
		printf("\t\t=====3、退出=====\n");
		printf("请输入功能选项:");
		scanf("%d",&menu);
		switch(menu)
		{
		case 1:
			{
				updown_file(cfd,sin);	
			}
			break;
		case 2:
			{
				download_file(cfd,sin);	
			}
			break;
		case 3:
			{
				close(cfd);
				return 0;
			}
			break;
		default:
			printf("输入错误\n");
		}
		printf("输入任意键按回车清屏\n");
		while(getchar()!='\n');
		system("clear");
	}


	return 0;
}
int download_file(int cfd,struct sockaddr_in sin)
{
	char buf[516]="";
	char fileName[20]="";
	printf("输入要下载的文件名:");
	scanf("%s",fileName);
	//发送请求下载文件
	short *p1=(short *)buf;  //p1指向操作码
	*p1=htons(1);
	char *p2=buf+2;          //p2指向文件名
	strcpy(p2,fileName);
	char *p3=p2+strlen(p2)+1;//p3指向模式名
	strcpy(p3,"octet");
	int len=4+strlen(p2)+strlen(p3);
	sendto(cfd,buf,len,0,(struct sockaddr*)&sin,sizeof(sin));
	socklen_t socklen=sizeof(sin);

	//fd打开目标文件
	char destfile[30]="./";
	strcat(destfile,fileName);
	int fd=-1;
	if((fd=open(destfile,O_WRONLY|O_TRUNC|O_CREAT,0664))==-1)
	{
		perror("open error");
		return -1;
	}

	int count=1;  //块编号
	short *p4=p1+1;//p4指向块编号的指针
	char *p5=buf+4;//p5写数据的指针
	memset(buf,0,sizeof(buf));
	while(1)
	{
		//读取数据放入buf
		int res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen);
		if(*p1==ntohs(3))//写入
		{
			count=ntohs(*p4);  //将块编号记录
			if(res<516)
			{
				write(fd,p5,res-4);
				printf("拷贝完成\n");
				break;
			}
			//写入数据
			if(write(fd,p5,512)==-1)
			{
				perror("write error");
				return -1;
			}else
			{
				memset(buf,0,sizeof(buf));
				*p1=htons(4);    //返回ack操作码为4
				*p4=htons(count);//返回块编号
				sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin));
			}
		}else if(*p1==ntohs(5))
		{
			puts("");
			printf("差错码为%d\n",*p2);
			printf("接收数据出错\n");
			return -1;
		}
	}
	close(fd);
}
int updown_file(int cfd,struct sockaddr_in sin)
{
	char buf[516]="";	
	char fileName[20]="";
	printf("输入要上传的文件名:");
	scanf("%s",fileName);

	//发送请求上传文件
	short *p1=(short *)buf;  //p1指向操作码
	*p1=htons(2);
	char *p2=buf+2;          //p2指向文件名
	strcpy(p2,fileName);
	char *p3=p2+strlen(p2)+1;//p3指向模式名
	strcpy(p3,"octet");
	int len=4+strlen(p2)+strlen(p3);
	sendto(cfd,buf,len,0,(struct sockaddr*)&sin,sizeof(sin));
	socklen_t socklen=sizeof(sin);

	//ufd打开目标文件
	char destfile[30]="./";
	strcat(destfile,fileName);
	int ufd=-1;
	if((ufd=open(destfile,O_RDONLY))==-1)
	{
		perror("open error");
		return -1;
	}
	int count=1;
	char *data_point=buf+4;
	short *cmd_point=(short*)buf;
	short *block_point=(short*)(buf+2);
	while(1)
	{
		recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen);
		if(*cmd_point==htons(4))
		{
			int res=read(ufd,buf+4,512);
			if(res==0)
			{
				printf("上传完成\n");
				break;
			}
			*cmd_point=htons(3);
			*block_point=htons(count++);
			sendto(cfd,buf,res+4,0,(struct sockaddr*)&sin,sizeof(sin));
		}else if(*cmd_point==htons(5))
		{
			printf("出错\t错误码%d\n",*block_point);
		}

	}
	close(ufd);
}

文章来源:https://blog.csdn.net/weixin_51597107/article/details/135661124
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。