Linux UDP下C语言实现TFTP协议客户端

本文介绍如何使用C语言在Linux环境下实现TFTP协议的UDP客户端,客户端具备上传和下载文件功能。在传输过程中,每个data包包含512字节数据,最后一个包数据不足512字节时表明传输结束。此外,协议需处理packet loss和重复数据包问题。
摘要由CSDN通过智能技术生成
        因课程实验要求,需要使用C语言在Linux下实现TFTP协议的客户端用于文件传输。TFTP,即Trivial File Transfer Protocol,有点类似于FTP协议不过要比FTP简单许多,功能也自然没FTP那么全。

       根据实验要求,客户端在与服务端传输文件的时候需要同时实现上传和下载功能,具体的功能由传输命令决定,如

-g small.txt xxxx.edu.cn
-p medium.pdf xxxx.edu.cn 
分别表示服务器xxxx.edu.cn下载文件small.txt和上传medium.pdf到服务端。

传输过程中,每个data packet携带固定长度512 bytes的data,如果某一个data packet携带的data长度小于512 bytes,则说明正在传输的是最后一个data packet,传输data结束且收到相应的ack packet后则表示整个传输过程结束,断开连接。

实验要求实现的协议必须能够处理packet loss和duplicated packet的情况。源代码如下:

tftp.h文件:

#ifndef _TFTP_H
#define _TFTP_H

#if defined(SUNOS_5)
#define OS_SUNOS5
typedef short u_int16_t;
typedef int u_int32_t;
typedef char u_int8_t;
#elif defined(__GNUC__) && (defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__))
#define OS_MACOSX
#elif defined(__GNUC__) && defined(__linux__)
#define OS_LINUX
#include <linux/types.h>
#else
#error "Unsupported operating system"
#endif 

#define BLOCK_SIZE 512

#define OPCODE_RRQ   1
#define OPCODE_WRQ   2
#define OPCODE_DATA  3
#define OPCODE_ACK   4
#define OPCODE_ERR   5


#define MODE_NETASCII "netascii"
#define MODE_OCTET    "octet"
#define MODE_MAIL     "mail"

#define TFTP_PORT 20069

/* Timeout in seconds */
#define TFTP_TIMEOUT 2

static char *err_codes[8] = {
	"Undef",
	"File not found",
	"Access violation",
	"Disk full or allocation exceeded",
	"Illegal TFTP operation",
	"Unknown transfer ID",
	"File already exists",
	"No such user"
};

/*
  A generic header for TFTP messages.
 */
struct tftp_msg {
	u_int16_t opcode;
	char msg[0];
};

/*
  A TFTP read request.
 */
struct tftp_rrq {
	u_int16_t opcode;
	char req[0];
};

#define TFTP_RRQ_HDR_LEN sizeof(struct tftp_rrq)
#define TFTP_RRQ_LEN(f,m) (sizeof(struct tftp_rrq) + strlen(f) + strlen(m) + 2)

/*
  A TFTP write request.
 */
struct tftp_wrq {
	u_int16_t opcode;
	char req[0];
};

#define TFTP_WRQ_HDR_LEN sizeof(struct tftp_wrq)
#define TFTP_WRQ_LEN(f,m) (sizeof(struct tftp_wrq) + strlen(f) + strlen(m) + 2)

/*
  A TFTP data block message.
 */
struct tftp_data {
	u_int16_t opcode;
	u_int16_t blocknr;
	char data[0];
};

#define TFTP_DATA_HDR_LEN sizeof(struct tftp_data)

/*
  A TFTP ack message.
 */
struct tftp_ack {
	u_int16_t opcode;
	u_int16_t blocknr;
};

#define TFTP_ACK_HDR_LEN sizeof(struct tftp_ack)

/*
  A TFTP error message.
 */
struct tftp_err {
	u_int16_t opcode;
	u_int16_t errcode;
	char errmsg[0];
};

#define TFTP_ERR_HDR_LEN sizeof(struct tftp_err)

static inline char *tftp_err_to_str(int err)
{
	if (err < 0 || err > 7)
		return NULL;
	
	return err_codes[err];
}

#endif /* TFTP_H_ */


tftp.c文件:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>

#include "tftp.
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值