1 // 客户端下载文件
2 #include <stdio.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <arpa/inet.h>
6 #include <netinet/in.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 int main(int argc, char const *argv[])
11 {
12 // 1.创建套接字
13 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
14 if (sockfd < 0)
15 {
16 perror("socket");
17 return -1;
18 }
19 // 2.创建文件用来保存下载文件的内容
20 int fd = open("a.txt", O_RDWR | O_CREAT, 0777);
21 // 3.指定服务器地址
22 struct sockaddr_in tftp_server_addr;
23 tftp_server_addr.sin_family = AF_INET;
24 tftp_server_addr.sin_port = htons(69);
25 tftp_server_addr.sin_addr.s_addr = inet_addr("10.9.42.228");
26 // 4.组请求+发送请求
27 char buf[128] = "";
28 int buflen = 0;
29 short id = 0;
30 buflen = sprintf(buf, "%c%c%s%c%s%c", 0, 1, "a.txt", 0, "netascii", 0);
31 sendto(sockfd, buf, buflen, 0, (struct sockaddr *)&tftp_server_addr, sizeof(tftp_server_addr));
32 // 5.循环收取数据
33 char recvbuf[1024] = "";
34 struct sockaddr_in tmp_server_addr;
35 socklen_t tmp_len = sizeof(tmp_server_addr);
36 while (1)
37 {
38 // 5.1清空数据内容以及地址结构
39 bzero(recvbuf, sizeof(recvbuf));
40 bzero(&tmp_server_addr, tmp_len);
41 // 5.2接收数据
42 buflen = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&tmp_server_addr, &tmp_len);
43 // 5.3判断
44 if (recvbuf[1] == 5)
45 {
46 printf("差错消息:%s\n", recvbuf + 4);
47 break;
48 }
49 else
50 {
51 recvbuf[1] = 4;
52 sendto(sockfd, recvbuf, 4, 0, (struct sockaddr *)&tmp_server_addr, tmp_len);
53 // 将内容保存文件
54 write(fd, recvbuf + 4, buflen - 4);
55 // 提取数据包的编号
56 id = ntohs(*((unsigned short *)(recvbuf + 2)));
57 printf("收到%d数据包 数据长度%d\n", id, buflen - 4);
58 // 如果数据小于512,数据包长度小于516,传输结束
59 if (buflen < 516)
60 break;
61 }
62 }
63 // 6.关闭套接字
64 close(sockfd);
65 close(fd);
66 return 0;
67 }