7.6 作业

1. 将UDP的服务器客户端重新搭建

#include <myhead.h>
#define ERR_MSG(msg) fprintf(stderr,"%d\n",__LINE__);perror(msg);
#define IP "192.168.10.151"
int main(int argc,const char *argv[])
{
	//创建套接字
	int sfd = socket(AF_INET,SOCK_DGRAM,0);
	if(sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	puts("socket success");

	//绑定ip和端口
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	addr.sin_addr.s_addr = inet_addr(IP);
	if(bind(sfd,(struct sockaddr *)&addr,sizeof(addr)))
	{
		ERR_MSG("bind");
		return -1;
	}
	puts("bind success");
	
	//接收数据
	while(1)
	{
		char a[128]="\0";
		struct sockaddr_in cli;
		socklen_t clilen = sizeof(cli);
		int ser = recvfrom(sfd,a,sizeof(a),0,(struct sockaddr *)&cli,&clilen);
		if(ser < 0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
		printf("[%s:%d]%s\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port),a);
		/*
		printf("发送数据:");
		fflush(stdout);
		bzero(a,sizeof(a));
		fgets(a,sizeof(a),stdin);
		a[strlen(a)-1] = '\0';
		*/
		if(sendto(sfd,a,sizeof(a),0,(struct sockaddr *)&cli,sizeof(cli)) < 0)
		{
			ERR_MSG("sendto");
			return -1;
		}
	}	
	
	//发送数据
	//关闭文件
	close(sfd);
	return 0;
}
#include <myhead.h>
#define ERR_MSG(msg) fprintf(stderr,"%d\n",__LINE__);perror(msg);
#define IP "192.168.10.151"
int main(int argc,const char *argv[])
{
	//创建套接字
	int sfd = socket(AF_INET,SOCK_DGRAM,0);
	if(sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	puts("socket success");

	//绑定ip和端口
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	addr.sin_addr.s_addr = inet_addr(IP);
	if(bind(sfd,(struct sockaddr *)&addr,sizeof(addr)))
	{
		ERR_MSG("bind");
		return -1;
	}
	puts("bind success");
//1	
	addr.sin_port = htons(2222);
	addr.sin_addr.s_addr = inet_addr("192.168.10.149");
	connect(sfd,(struct sockaddr *)&addr,sizeof(addr));
//2	
	addr.sin_family =  AF_UNSPEC;
	addr.sin_port = htons(2222);
	addr.sin_addr.s_addr = inet_addr("192.168.10.149");
	connect(sfd,(struct sockaddr *)&addr,sizeof(addr));


	//接收数据
	while(1)
	{
		char a[128]="\0";
		struct sockaddr_in cli;
		socklen_t clilen = sizeof(cli);
		int ser = recvfrom(sfd,a,sizeof(a),0,(struct sockaddr *)&cli,&clilen);
		if(ser < 0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
		printf("[%s:%d]%s\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port),a);	
	}	
	
	//发送数据
	//关闭文件
	close(sfd);
	return 0;
}

 


2. 编写tftp的下载代码

#include <myhead.h>
#define ERR_MSG(msg) fprintf(stderr,"%d\n",__LINE__);perror(msg);
#define IP "192.168.10.149"
typedef struct{
	uint16_t opcode;
	uint16_t block;
	uint8_t data[512];
}datapag;
typedef struct{
	uint16_t opcode;
	uint16_t block;
}ack;

int download(int cfd,const struct sockaddr_in *addr,int addrlen)
{	//发送数据
	char buf[128]="";
	char *ptr = buf;
	*(uint16_t *)ptr = htons(1);
	ptr += 2;
	char fname[20] = "";
	printf("输入文件名:");
	scanf("%s",fname);
	strcpy(ptr,fname);
	ptr += strlen(fname)+1;
	strcpy(ptr,"octet");
	if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr *)addr,addrlen) < 0)//发送请求
	{
		ERR_MSG("sendto");
		return -1;
	}

	ack a={htons(4),htons(0)};//ack
	int f = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0664);//打开文件往里面放数据
	if(f<0)
	{
		ERR_MSG("open file");
		return -1;
	}
	while(1)
	{
		struct sockaddr_in ser;
		socklen_t serlen = sizeof(ser);
		datapag pg;
		printf("1\n");
		ssize_t len = recvfrom(cfd,&pg,sizeof(pg),0,(struct sockaddr *)&ser,&serlen);//获得数据包和服务器地址
		if (len < 0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}

		a.block = pg.block;//修改ack的块编号
		printf("2 %d\n",ntohs(a.block));
		if(sendto(cfd,&a,sizeof(a),0,(struct sockaddr *)&ser,serlen) < 0)//发送ack
		{
			ERR_MSG("sendto");
			return -1;
		}

		printf("3 %ld\n",len);
		if(write(f,pg.data,len - 4) < 0)//往文件中写数据
		{
			ERR_MSG("write");
			return -1;
		}
		if(len-4 < 512)//数据不足512则执行结束
		{
			puts("传输完成");
			close(f);
			return 0;
		}
	}
}

int main(int argc,const char *argv[])
{
	//创建套接字
	int cfd = socket(AF_INET,SOCK_DGRAM,0);
	if(cfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	puts("socket success");

	struct sockaddr_in addr;//服务器地址
	addr.sin_family = AF_INET;
	addr.sin_port = htons(69);
	addr.sin_addr.s_addr = inet_addr(IP);
	socklen_t addrlen = sizeof(addr);

	char c = 0;
	while(1)
	{
		puts("1.上传");
		puts("2.下载");
		puts("3.退出");
		c = getchar();
		while(getchar()!='\n');
		if(c=='3')
			break;
		switch(c)
		{
		case '1':
			break;
		case '2':
			download(cfd,&addr,addrlen);//下载函数
			break;
		}
	}

	//关闭文件
	close(cfd);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值