#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;
}
客户端下载
于 2023-08-13 10:56:35 首次发布