【TFTP】客户端上传文件

发布时间 2023-12-14 21:51:25作者: 素装写淡定
 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);
21     if (fd < 0)
22     {
23         perror("open");
24         return -1;
25     }
26     // 3.指定服务器地址
27     struct sockaddr_in tftp_server_addr;
28     tftp_server_addr.sin_family = AF_INET;
29     tftp_server_addr.sin_port = htons(69);
30     tftp_server_addr.sin_addr.s_addr = inet_addr("10.9.42.228");
31     // 4.组上传请求+发送请求
32     char buf[128] = "";
33     int buflen = 0, readlen = 0;
34     buflen = sprintf(buf, "%c%c%s%c%s%c", 0, 2, "a.txt", 0, "netascii", 0);
35     sendto(sockfd, buf, buflen, 0, (struct sockaddr *)&tftp_server_addr, sizeof(tftp_server_addr));
36     // 5.循环收取数据
37     char recvbuf[1024] = "";
38     struct sockaddr_in tmp_server_addr;
39     socklen_t tmp_len = sizeof(tmp_server_addr);
40     unsigned short id = 0;
41     while (1)
42     {
43         // 5.1清空地址和数据内容
44         bzero(recvbuf, sizeof(recvbuf));
45         bzero(&tmp_server_addr, tmp_len);
46         // 5.2收取数据recvfrom
47         buflen = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&tmp_server_addr, &tmp_len);
48         // 5.3判断
49         if (recvbuf[5] == 5) // recvbuf=05 00
50         {
51             // 如果是差错包--打印出错信息,break
52             printf("差错信息:%s\n", recvbuf + 4);
53             break;
54         }
55         else // recvbuf=04 00
56         {
57             recvbuf[1] = 3;
58             id = ntohs(*((unsigned short *)(recvbuf + 2)));
59             id += 1;
60             *((unsigned short *)(recvbuf + 2)) = htons(id);
61             readlen = read(fd, recvbuf + 4, 512);
62             printf("即将发送%d数据包, 数据包长度%d\n", id, readlen);
63             sendto(sockfd, recvbuf, readlen + 4, 0, (struct sockaddr *)&tmp_server_addr, &tmp_len);
64             // 如果读文件内容len<512,break
65             if (readlen < 512)
66                 break;
67         }
68     }
69     // 6.关闭套接字
70     close(fd);
71     close(sockfd);
72     return 0;
73 }