代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#define ERR_MSG(msg) do{\
fprintf(stderr, "line:%d\n", __LINE__);\
perror(msg);\
}while(0)
#define IP "192.168.8.88" //填你们自己的本机IP ifconfig查看
#define PORT 69 //1024~49151
int main(int argc, const char *argv[])
{
//创建报式套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sfd < 0)
{
ERR_MSG("socket");
return -1;
}
//打开文件
int fd = open("./1.png",O_RDWR|O_CREAT|O_TRUNC,0664);
if(fd<0)
{
ERR_MSG("open");
return -1;
}
//绑定客户端自身的地址信息结构体-->非必须绑定,建议不写
//填充服务器自身的地址信息结构体,AF_INET: man 7 IP
//供于下方的sendto使用,因为sendto必须要指明发给谁
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
socklen_t addrlen = sizeof(sin);
char buf[128] = "";
ssize_t res = 0;
ssize_t resf = 0;
char rec[550] = "";
short *p6 = NULL;
//组下载协议
short *p1 = (short *)buf;
*p1 = htons(1);
char *p2 = buf + 2;
strcpy(p2,"5.png");
char *p3 = p2 + strlen(p2);
*p3 = 0;
char *p4 = p3 + 1;
strcpy(p4,"octet");
int size = 2 + strlen(p2) + 1 + strlen(p4) + 1;
//发送下载协议
if(sendto(sfd,buf,size,0,(struct sockaddr *)&sin,addrlen)<0)
{
ERR_MSG("sendto");
return -1;
}
printf("sendto success\n");
while(1)
{
bzero(rec,sizeof(rec));
//接收数据包
resf = recvfrom(sfd,rec,sizeof(rec),0,(struct sockaddr *)&sin,&addrlen);
if(resf<0)
{
ERR_MSG("recvfrom");
return -1;
}
else if(0 == resf)
{
printf("服务器下线\n");
break;
}
//将接收到的数据写入到文件中
res = write(fd,rec+4,resf-4);
if(res<0)
{
ERR_MSG("write");
return -1;
}
p6 = (short *)rec;
*p6 = htons(4);
//返回块编号
if(sendto(sfd,rec,4,0,(struct sockaddr *)&sin,addrlen)<0)
{
ERR_MSG("sendto");
return -1;
}
if((resf-4)<512)
{
printf("读取完毕\n");
break;
}
}
//关闭套接字
close(sfd);
close(fd);
return 0;
}
代码执行结果:
ubuntu@ubuntu:net$ gcc 14test.c
ubuntu@ubuntu:net$ ./a.out
sendto success
读取完毕