网络编程 - 20230608

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值