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 }