tftp
客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <pthread.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define ERROR_MSG(msg) do{\
fprintf(stderr, "line:%d: %s %s", __LINE__, __FILE__, __func__);\
perror(msg);\
}while(0)
#define SUCCESS_MSG(msg) do {\
printf("%s, line:%d \n", msg, __LINE__);\
}while(0)
#define IP "192.168.50.130"
#define PORT 69
int main(int argc, const char *argv[]) {
if (argc != 2) {
printf("参数错误\n");
return -1;
}
int cfd = socket(AF_INET, SOCK_DGRAM, 0);
if (cfd < 0) {
ERROR_MSG("socket:");
return -1;
}
SUCCESS_MSG("socket success:");
//配置读写请求
char buf[516] = "";
char filename[20];
strcpy(filename, argv[1]);
int size = sprintf(buf, "%c%c%s%c%s%c", 0, 1, filename, 0, "octet", 0);
struct sockaddr_in cin;
cin.sin_family = AF_INET;
cin.sin_port = htons(PORT);
cin.sin_addr.s_addr = inet_addr(IP);
if (sendto(cfd, buf, size, 0, (struct sockaddr *)&cin, sizeof(cin))<0) {
ERROR_MSG(" sendto error:");
return -1;
}
SUCCESS_MSG("发送读写请求成功");
//接收数据包
struct sockaddr_in sin;
int sinLen = sizeof(sin);
int firstRecv = 1;
while(1) {
bzero(buf, sizeof(buf));
int recvLen = recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, &sinLen);
printf("recvLen = %d \n", recvLen);
if (recvLen < 0) {
ERROR_MSG(" recvfrom error:");
return -1;
} else {
short *op_ptr = (short *)buf;
short *block_ptr = op_ptr + 1;
short op_val = ntohs(*op_ptr); //操作码
short block_val = ntohs(*block_ptr); //块编号
printf("操作码 = %d, 块编号 = %d\n", op_val, block_val);
char *con_ptr = (char *)block_ptr + 2;
printf("content: %s \n", con_ptr);
//ERROR的情况
if (op_val == 5) {
printf("数据包Error: %s \n", con_ptr);
} else {
//数据包成功的情况
int conLen = recvLen-4;
char pathname[128];
sprintf(pathname, "./%s", filename);
int fid = open(pathname, O_WRONLY|O_CREAT|(firstRecv ? O_TRUNC : O_APPEND), 0664);
firstRecv = 0;
if (fid < 0) {
ERROR_MSG("file open:");
return -1;
}
write(fid, con_ptr, conLen);
close(fid);
char ack[4] = "";
short *ack_op = (short *)ack;
*ack_op = htons(4);
short *ack_block = ack_op+1;
*ack_block = *block_ptr;
printf("block = %d ", block_val);
printf("port: %d, addr: %s \n", ntohs(sin.sin_port), inet_ntoa(sin.sin_addr));
if (sendto(cfd, ack, sizeof(ack), 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
ERROR_MSG("sendto error: ");
return -1;
}
if (conLen < 512) {
//传输完成
SUCCESS_MSG("复制成功 ");
break;
}
}
}
SUCCESS_MSG(" 接收数据包成功 ");
}
close(cfd);
return 0;
}