8.10 作业

#include <head.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
 
 
#define PORT 69
#define IP "192.168.2.11"
#define NAME "5.png"
 
int main()
{
	printf("<===========客户端下载===========>\n");
	//创建报文套接字
	int sfd = socket(AF_INET,SOCK_DGRAM,0);
	if(sfd < 0)
	{
		perror("socket--> ");
		return -1;
	}
	
	//填充地址消息结构体,真实地址消息结构体根据地址族制定
	struct sockaddr_in sin;//定义结构体(给结构体内的每个元素赋值)
	sin.sin_family      = AF_INET;//网络协议-IPV4
	sin.sin_port        = htons(PORT);//端口号1024-69151
	sin.sin_addr.s_addr = inet_addr(IP);//uabntu的本机ip地址
	socklen_t addrlen = sizeof(sin);
 
	//下载数据包赋值
	char buf[516] = "";
	char *p = buf;
 
	unsigned short *p1 = (unsigned short*)buf;//操作码2byte;
	*p1 = htons(1);
 
	char *p2 = (char *)p1+1;//NAME Xbyte;
	strcpy(p2,NAME);
 
	char *p3 = (char*)(p1+strlen(p2));
	*p3 = 0;
 
	char *p4 = (char*)(p1+strlen(p2)+1);//模式 nbyte;
	strcpy(p4,"octet");
	
	size_t sizeall = 2+strlen(p2)+1+strlen(p4)+1;//总字节大小 
 
	//创建图片文件用于接收
	int fdw = open("./5.png",O_WRONLY|O_CREAT|O_TRUNC,0777);
	if(fdw < 0)
	{
		perror("open---> ");
		return -1;
	}
	//发送请求
	int res2 = sendto(sfd,buf,sizeall,0,(struct sockaddr*)&sin,addrlen);
	if(res2 < 0)
	{
		perror("sendto--> ");
		return -1;
	}
	printf("sendto success\n");
 
 
 
	ssize_t res = 0;
	ssize_t res1 = 0;
	int k = 1;
	char *pw = p+4;//读取数据的地址(操作码2byte+块编号2byte)
	while(k)
	{
		//接收(发送者)服务器的消息
		bzero(buf,sizeof(buf));
		res = recvfrom(sfd,buf,516,0,(struct sockaddr*)&sin,&addrlen);
		if(res < 0)
		{
			perror("recvfrom--> ");
			return -1;
		}
		printf("recvfrom -- success res-->%ld\n",res);
 
		write(fdw,pw,res-4);//写入数据
		*(p+1) = htons(4);//ACK操作码赋值为4
 
 
 
		//发送消息给服务器
		res1 = sendto(sfd,buf,4,0,(struct sockaddr*)&sin,addrlen);//4 <==> ACK操作码
		if(res1 < 0)
		{
			perror("sendto--> ");
			return -1;
		}
		printf("sendto ACK success res1-->%ld\n",res1);
 
		if(res < 516)
		{
			break;
		}
 
	}
 
 
	//关闭套接字
	
	close(sfd);
	close(fdw);
 
	return 0;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
08-14 123
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值