tftp 源代码解析

本文分析了tftpx项目中的客户端代码,包括tftpx.h、client.h和client.c三个文件。主要讨论了停止等待机制如何影响tftp的速度,并介绍了do_list、do_get和do_put等关键函数。通过示例计算,说明了tftp速度较慢的原因,提出改进速度的可能方案。
摘要由CSDN通过智能技术生成

我先研究udp 传输的机制,tftp是用udp 设计的一个不错应用。

在网上查找tftp 源代码,发现 https://github.com/ideawu/tftpx 上的源码比较好看,这个只是linux 下的代码。

在ubuntu 上make 了一下,就编译好了,然后测试程序,能按tftp 的方式运行。

那个链接包含服务端和客户端代码,我这里只是分析其客户端代码,因为就算客户端代码也很大的,相比其他的代码,这个还是算简单的。

这个客户端代码包含3个文件,

tftpx.h 定义tftp中的常量,与服务端程序共享。

client.h 就是几个函数的全局定义。

client.c 这个是主程序。

在查看 tftpx 的源码之前, 你最好先阅读 W.Richard.Stevens 的 TCP/IP Illustrated Volume 1: The Protocols(TCP/IP详解 卷1:协议).

tftpx 使用这样的代码来实现停止等待机制:

int send_packet(int sock, struct tftpx_packet *packet, int size){
	struct tftpx_packet rcv_packet;
	int time_wait_ack = 0;
	int rxmt = 0;
	int r_size = 0;

	for(rxmt = 0; rxmt < PKT_MAX_RXMT; rxmt ++){
		printf("Send block=%d\n", ntohs(packet->block));
		if(send(sock, packet, size, 0) != size){
			return -1;
		}
		for(time_wait_ack = 0; time_wait_ack < PKT_RCV_TIMEOUT; time_wait_ack += 20000){
			usleep(20000);
			// Try receive(Nonblock receive).
			r_size = recv(sock, &rcv_packet, sizeof(struct tftpx_packet), MSG_DONTWAIT);
			if(r_size >= 4 && rcv_packet.cmd == htons(CMD_ACK) && rcv_packet.block == packet->block){
				//printf("ACK: block=%d\n", ntohs(rcv_packet.block));
				// Valid ACK
				break;
			}
		}
		if(time_wait_ack < PKT_RCV_TIMEOUT){
			break;
		}else{
			// Retransmission.
			continue;
		}
	}
	if(rxmt == PKT_MAX_RXMT){
		// send timeout
		printf("Sent packet exceeded PKT_MAX_RXMT.\n");
		return -1;
	}

	return size;
}

tftp 的速度问题 

从这个停止等待机制看,tftp 速度应该有点慢。

网上搜索tftp 速度,结果都说慢,都怀疑网络问题,从这个机制我们可以评估速度。因为usleep(20000)需要20ms 才能传一个包,一个包大小一般512字节,理想情况下 512x50=25600 字节/秒  50=1000/20

所以传送速度就是25k 字节/秒

这个usleep(20000) 可能有点不得已,每个包都要核实好了,才能下一个包,可能比ftp 都会慢。

要提高速度可以加大包的尺寸,减少usleep的数据。

或者采用多个包才核实等传送机制,如果就tftp 可能没办法。

主要的几个函数

void do_list(int sock, char *dir);  实现目录列表
void do_get(char *remote_file, char *local_file);  从服务端获取文件的实现
void do_put(char *filename);  发送文件到服务端

int main(int argc, char **argv) 这个是主函数

命令行分析,必须输入服务端的ip 地址, 端口号是可选的,如果与他的服务程序通讯,就是缺省为:

#define SERVER_PORT 10220

在建立通讯sock前,显示应用帮助文件

建立一个sock ,没有通讯测试一样

然后等待你输入tftp 命令,解析命令,然后调用上面3个函数,完成功能。

支持的tftp命令是 list,get,put,blocksize,quit

可以看帮助文件的函数实现:

void help(){
	printf("Usage: cmd  arg0[,arg1,arg2...]\n");
	printf("  -Directory listing:\n");
	printf("    list path\n");
	printf("  -Download a file from the server:\n");
	printf("    get remote_file[ local_file]\n");
	printf("  -Upl
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值