TFTP搭建的下载与上传

1. 将UDP服务器客户端脱离笔记重新搭建(上交)
2. 完成下载上传(上交,必须完成下载,上传尽力完成)

TFTP下载

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ERR_MSG(msg) do{fprintf(stderr,"line:%d",__LINE__);perror(msg);}while(0)

#define TFTP_SER_PORT 69
#define SER_IP "192.168.0.144"


int main(int argc, const char *argv[])
{

	//创建报式套接字
	int  cfd = socket(AF_INET,SOCK_DGRAM,0);
	if(cfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("socket create success cfd = %d __%d__\n",cfd,__LINE__);

	//填充服务器地址信息
	struct sockaddr_in sin;
	sin.sin_family   =   AF_INET;
	sin.sin_port     =   htons(TFTP_SER_PORT);//端口号
	sin.sin_addr.s_addr   =   inet_addr(SER_IP);//TFTP地址

	//发送下载请求
	char buf[516] = "";
	bzero(buf,sizeof(buf));

	unsigned short * p1 = (unsigned short *)buf;
	*p1 = htons(1);  //操作码
	
	char *p2 = buf + 2;
	char filename[1024]="";
	printf("输入要下载的文件名>>>>>");
	scanf("%s",filename);
	getchar();
	strcpy(p2,filename);   //下载的文件

	char *p3 = p2 + strlen(p2);
	*p3 = 0;

	char *p4 = p3 + 1;
	strcpy(p4,"octet");

	char *p5 = p4 + strlen(p4);

	int size = 2+1+1+strlen(p2)+strlen(p4);

//常用组包
//	int size = sprintf(buf,"%c%c %s%c%s%c",0x00,0x01,"1_armcli.c",0,"octet",0);
	ssize_t ret = sendto(cfd,buf,size,0,(struct sockaddr *)&sin,sizeof(sin));
	if(ret < 0)
	{
		ERR_MSG("sendto");
		return -1;	
	}
	printf("sendto success\n");
	
	socklen_t addrlen = sizeof(sin);
	//打开文件
	int fd;
	ssize_t recv_len;
	ssize_t res = 0;
//	unsigned short num = 0;

	while(1)
		{
			//接收服务器发送的数据包
			bzero(buf,sizeof(buf));
			recv_len = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr *)&sin,&addrlen);
			if(recv_len < 0)
			{
				ERR_MSG("recvfrom");
				return -1;
			}
			printf("recvfrom success\n");

			//错误包,打印错误码+错误信,退出
			if(buf[1] == 0x05)
			{
				fprintf(stderr,"download failed __%d__%s\n",ntohs(*(short *)(buf + 2)),buf + 4);
				break;
			}

			//是数据包,提取数据包中的数据(buf+4),另存文件当中
			else if(buf[1] == 0x03)
			{
				printf("get file\n");
				fd = open(filename,O_WRONLY | O_CREAT | O_APPEND,0666);
				if(fd < 0)
				{
					ERR_MSG("open");
					return -1;
				}
				
				//给服务器回复ACK,组ACK包,快编号域接收到的数据包快编号一致
				if(write(fd,buf+4,recv_len-4)<0)
				{
					ERR_MSG("write");
					ret = -1;
					break;
				}
				printf("write success\n");

				buf[1] == 0x04;
				if(sendto(cfd,buf,4,0,(struct sockaddr *)&sin,sizeof(sin) )< 0)
				{
					ERR_MSG("sendto");
					return -1;
				}
				printf("sendto success\n");

				if(recv_len < 512)
					break;

				close(fd);
			}
		}

	printf("dowload compare\n");
	//关闭
	close(cfd);
	return 0;
}

服务器

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ERR_MSG(msg) do{fprintf(stderr,"line:%d",__LINE__);perror(msg);}while(0)

#define PORT 1052
#define IP "192.168.0.119"

int main(int argc, const char *argv[])
{

	//创建报式套接字
	int  sfd = socket(AF_INET,SOCK_DGRAM,0);
	if(sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("socket create success sfd = %d __%d__\n",sfd,__LINE__);

	//填充服务器地址信息
	struct sockaddr_in sin;
	sin.sin_family   =   AF_INET;
	sin.sin_port     =   htons(PORT);//端口号
	sin.sin_addr.s_addr   =   inet_addr(IP);//IP地址

	//绑定
	if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind  success sfd = __%d__\n",__LINE__);


	char buf[1024] = "";
	ssize_t res = 0;

	struct sockaddr_in cin;
	socklen_t addrlen = sizeof(cin);
	while(1)
	{
		bzero(buf,sizeof(buf));//清空
		//接收
		res = recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&cin,&addrlen);
		if(res < 0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
		printf("[ %s : %d ]:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf);
		//发送
		strcat(buf,"=_=");
		if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr *)&cin,sizeof(cin)) < 0)
		{
			ERR_MSG("sendto");
			return -1;
		}
		printf("sendto success\n");
	}
	//关闭
	close(sfd);
	return 0;
}

客户端

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ERR_MSG(msg) do{fprintf(stderr,"line:%d",__LINE__);perror(msg);}while(0)

#define SER_PORT 1053
#define SER_IP "192.168.0.119"

#define CLI_PORT 1053
#define CLI_IP "192.168.0.119"

int main(int argc, const char *argv[])
{

	//创建报式套接字
	int  cfd = socket(AF_INET,SOCK_DGRAM,0);
	if(cfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("socket create success cfd = %d __%d__\n",cfd,__LINE__);

	//填充服务器地址信息
	struct sockaddr_in sin;
	sin.sin_family   =   AF_INET;
	sin.sin_port     =   htons(SER_PORT);//端口号
	sin.sin_addr.s_addr   =   inet_addr(SER_IP);//IP地址

	//绑定
	struct sockaddr_in cin;
	sin.sin_family   =   AF_INET;
	sin.sin_port     =   htons(CLI_PORT);//端口号
	sin.sin_addr.s_addr   =   inet_addr(CLI_IP);//IP地址


	if(bind(cfd,(struct sockaddr *)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind  success sfd = __%d__\n",__LINE__);


	char buf[1024] = "";
	ssize_t res = 0;

	struct sockaddr_in recvaddr;
	socklen_t addrlen = sizeof(recvaddr);
	while(1)
	{
		bzero(buf,sizeof(buf));//清空
	
		//发送
		printf("Input>>>>");
		fgets(buf,sizeof(buf),stdin);
		buf[strlen(buf)-1] = '\0';
		if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr *)&sin,sizeof(sin)) < 0)
		{
			ERR_MSG("sendto");
			return -1;
		}

		//接收数据
		bzero(buf,sizeof(buf));
		res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr *)&recvaddr,&addrlen);
		if(res < 0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
		printf("[ %s : %d ]:%s\n",inet_ntoa(recvaddr.sin_addr),ntohs(recvaddr.sin_port),buf);
	}
	//关闭
	close(cfd);
	return 0;
}

你可能感兴趣的:(udp,网络,网络协议)