【TFTP】客户端下载文件代码

发布时间 2023-12-13 22:58:00作者: 素装写淡定
 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 }