以下是一个简单的TFTP客户端的C语言例子,可以用于向服务器请求下载文件:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define TFTP_PORT 69
typedef struct {
unsigned short opcode;
union {
unsigned short block_num;
unsigned short error_code;
char data[1];
} data;
} tftp_packet;
int main(int argc, char *argv[]) {
if(argc != 3) {
printf("Usage: %s <server_ip> <file_name>\n", argv[0]);
exit(1);
}
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0) {
perror("socket");
exit(1);
}
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(TFTP_PORT);
if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
perror("inet_pton");
exit(1);
}
tftp_packet *packet = (tftp_packet *)malloc(sizeof(tftp_packet) + strlen(argv[2]) + 1);
packet->opcode = htons(1);
strcpy(packet->data.data, argv[2]);
sendto(sockfd, packet, sizeof(tftp_packet) + strlen(argv[2]) + 1, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
FILE *fp = fopen(argv[2], "wb");
if(fp == NULL) {
perror("fopen");
exit(1);
}
int block_num = 1;
while(1) {
tftp_packet *packet = (tftp_packet *)malloc(sizeof(tftp_packet) + 512);
socklen_t addrlen = sizeof(servaddr);
int n = recvfrom(sockfd, packet, sizeof(tftp_packet) + 512, 0, (struct sockaddr *)&servaddr, &addrlen);
if(n < 0) {
perror("recvfrom");
exit(1);
}
if(ntohs(packet->opcode) == 3) {
if(ntohs(packet->data.block_num) == block_num) {
fwrite(packet->data.data, 1, n - sizeof(tftp_packet), fp);
block_num++;
}
packet->opcode = htons(4);
packet->data.block_num = htons(block_num - 1);
sendto(sockfd, packet, sizeof(tftp_packet), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
if(n - sizeof(tftp_packet) < 512) {
break;
}
} else if(ntohs(packet->opcode) == 5) {
printf("Error: %d\n", ntohs(packet->data.error_code));
exit(1);
}
}
fclose(fp);
close(sockfd);
return 0;
}
该例子中,客户端向服务器发送一个读请求,请求下载指定文件。客户端接收到服务器的数据包后,将数据写入本地文件中。同时,客户端还需要发送确认包给服务器,以确认已经接收到数据包。如果服务器返回错误信息,则客户端需要打印错误信息并退出。
【最后一个bug】多平台都有更新和发布,大家可以一键三连,关注+星标,不错过精彩内容~~