8.18作业

发布于:2025-08-19 ⋅ 阅读:(17) ⋅ 点赞:(0)

1.基于UDP的TFTP文件传输

#include <25061head.h>
#define SER_IP "192.168.108.192"
#define SER_PORT 69
#define CLI_IP "192.168.109.126"
#define CLI_PORT 9999

int main(int argc, const char *argv[])
{
	int cfd=socket(AF_INET,SOCK_DGRAM,0);
	if(-1==cfd)
	{
		ERR_MSG("socket error");
	}
	printf("socket success cfd=%d\n",cfd);

	struct sockaddr_in cin;
	cin.sin_family=AF_INET;
	cin.sin_port=htons(CLI_PORT);
	cin.sin_addr.s_addr=inet_addr(CLI_IP);

	if(bind(cfd,(struct sockaddr*)&cin,sizeof(cin))==-1)
	{
		ERR_MSG("bind error");
	}
	printf("bind success\n");

	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(SER_PORT);
	sin.sin_addr.s_addr=inet_addr(SER_IP);
	socklen_t addrlen=sizeof(sin);

	char msgbuf[516]="";
	char filename[256]="";
	printf("请输入下载的文件名:");
	scanf("%s",filename);

	short *p1=msgbuf;
	*p1=htons(1);

	char *p2=msgbuf+2;
	strcpy(p2,filename);

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

	int msglen=2+strlen(p2)+strlen(p4)+2;

	if(-1==sendto(cfd,msgbuf,msglen,0,(struct sockaddr*)&sin,sizeof(sin)))
	{
		close(cfd);
		ERR_MSG("sendto error");
	}

	int fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664);
	if(fd==-1)
	{
		close(cfd);
		ERR_MSG("open error");
	}
	struct sockaddr_in addr;
	socklen_t len=sizeof(addr);
	unsigned short block=0;
	int res;
	short opcode;

	while(1)
	{
		res=recvfrom(cfd,msgbuf,sizeof(msgbuf),0,(struct sockaddr*)&addr,&len);
		if(-1==res)
		{
			close(fd);
			close(cfd);
			ERR_MSG("recvfrom error");
		}

		opcode=ntohs(*(short*)msgbuf);

		if(opcode==3)
		{
			unsigned short block_num=ntohs(*(unsigned short*)(msgbuf+2));
			if(block_num==block+1)
			{
				block=block_num;
				int datalen=res-4;
				ssize_t w=write(fd,msgbuf+4,datalen);
				if(w<0)
				{
					close(fd);
					close(cfd);
					ERR_MSG("write error");
					return -1;
				}
				*(short*)msgbuf=htons(4);
				*(unsigned short*)(msgbuf+2)=htons(block);

				if(sendto(cfd,msgbuf,4,0,(struct sockaddr*)&addr,len)==-1)
				{
					close(fd);
					close(cfd);
					ERR_MSG("sendto error");
					return -1;
				}
				if(datalen<512)
				{
					printf("下载完成\n");
					close(fd);
					return 0;
				}
			}
			else if(block_num==block)
			{
				*(short*)msgbuf=htons(4);
				*(unsigned short*)(msgbuf+2)=htons(block);
				if(-1==sendto(cfd,msgbuf,4,0,(struct sockaddr*)&addr,len))
				{
					close(fd);
					close(cfd);
					ERR_MSG("sendto error");
					return -1;
				}
			}
			else
			{
				printf("error\n");
			}
		}
		else if(opcode==5)
		{
			unsigned short error_code=ntohs(*(unsigned short*)(msgbuf+2));
			char *error_msg=msgbuf+4;
			printf("错误:%d-%s\n",error_code,error_msg);
			close(fd);
			close(cfd);
			return -1;
		}
		else
		{
			printf("未知:%d\n",opcode);
			close(fd);
			close(cfd);
			return -1;
		}
	}

	close(cfd);
	return 0;
}

2.


网站公告

今日签到

点亮在社区的每一天
去签到