8月29日作业

思维导图

tftp下载

#include<myhead.h>

#define PORT 69
#define IP "192.168.114.122"

int do_download(int client_socket, struct sockaddr_in server_addr);
int do_upload(int client_socket, struct sockaddr_in server_addr);

int main(int argc, const char *argv[])
{
	//新建套接字文件
	int client_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if(client_socket == -1){
		ERR_MSG("socket");
		return -1;
	}
	printf("socket success\n");


	//定义要发送的地址信息结构体
	struct sockaddr_in server_addr;
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.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); //循环吸收垃圾字符

		switch(choose)
		{
		case '1':
			do_download(client_socket, server_addr);
			break;
		case '2':
			do_upload(client_socket, server_addr);
			break;
		case '3':
			goto END;
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}

		printf("请输入任意字符清屏>>>");
		while(getchar() != 10);
	}

#if 0
	char msg[128] = "hello world";/*{{{*//*{{{*/
	char buf[128] = "";
	ssize_t ret;
	while(1){
		//发送数据
		sleep(2);
		sendto(client_socket, msg, sizeof(msg), 0,\
				(const struct sockaddr *)&server_addr,\
				sizeof(server_addr));
		printf("已将%s发送给[%s:%d] client_socket = %d\n",msg,\
				inet_ntoa(server_addr.sin_addr),\
				ntohs(server_addr.sin_port), client_socket);
		//接收数据
		//清空字符串
		bzero(buf, sizeof(buf));
		socklen_t server_addr_len = sizeof(server_addr);
		ret = recv(client_socket, buf, sizeof(buf), 0);
		if(ret == -1){
			ERR_MSG("recvfrom");
			break;
		}

		printf("已将%s从[%s:%d]接收 client_socket = %d\n",buf,\
				inet_ntoa(server_addr.sin_addr),\
				ntohs(server_addr.sin_port), client_socket);
		putchar(10);
	}/*}}}*//*}}}*/
#endif
END:
	//关闭套接字文件
	if(close(client_socket) == -1){
		ERR_MSG("close");
		return -1;
	}

	return 0;
}


int do_download(int client_socket, struct sockaddr_in server_addr)
{
	char ack[4] = "";
	char buf[516] = "";
	char filename[20] = "";
	int ret;
	FILE *file = fopen("./received_image.png", "w");
	if(file == NULL)
	{
		ERR_MSG("fopen");
		return -1;
	}
	printf("请输入要下载的文件名\n");
	scanf("%s",filename);
	while(getchar() != 10);
	//组下载请求包
	unsigned short* ptr1 = (unsigned short*)buf;
	*ptr1 = htons(1);

	char *ptr2 = buf+2;
	strcpy(ptr2, filename);

	char *ptr3 = ptr2+strlen(filename)+1;
	strcpy(ptr3, "octet");
	int size = 2+strlen(ptr2)+strlen(ptr3)+2;

	//发送下载请求 sendto
	if(sendto(client_socket, buf, size, 0,\
					(struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
	{
		ERR_MSG("buf sendto");
		return -1;
	}
	printf("sendto download request success\n");

	while(1)
	{
		//接收数据 recvfrom, 接收地址信息
		bzero(buf, sizeof(buf));
		socklen_t server_addr_len = sizeof(server_addr);
		ret = recvfrom(client_socket, buf, sizeof(buf), 0,\
				(struct sockaddr*)&server_addr, &server_addr_len);
		printf("接收了%d个字符\n",ret);
		if(ret == -1)
		{
			ERR_MSG("recvfrom");
			break;
		}

		unsigned short opcode = ntohs(*(unsigned short*)buf);
		if(opcode == 3)
		{
			fwrite(buf+4, 1, ret-4, file);
		}else if(opcode == 5)
		{
			ERR_MSG("opcode");
			break;
		}

		//组ack包
		unsigned short *ptr4 = (unsigned short*)ack;
		*ptr4 = htons(4);

		unsigned short *ptr5 = ptr4+1;
		*ptr5 = *(unsigned short*)(buf+2);

		//发送ack sendto
		if(sendto(client_socket, ack, 4, 0,\
			(struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
		{
			ERR_MSG("ack sendto");
			return -1;
		}
		printf("ack sendto success\n");
		//判断数据是否小于512字节,若小于则下载完成
		if(ret < 516)
		{
			printf("download success\n");
			break;
		}
	}
	fclose(file);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值