免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1761 | 回复: 1
打印 上一主题 下一主题

基于tftp简单文件传输协议下载客服端的实现 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-05 16:01 |只看该作者 |倒序浏览

    TFTP协议是基于udp协议的简单文件传输协议,最早用于引导无盘系统,在网吧比较常见,其数据传输过程及实现原理如下(具体的报文格式这里不在详细介绍):
1、客服端向服务器端发送读写请求(读写报文)
2、服务器端向客服端发送回应信息
3、客服端向服务器端发送确认信息包(ack)
4、服务器段向克服端发送数据包
5、客服端向服务器端发确认信息包(ack)
  --------数据包发送结束------

//===============================================================
//The information contained herein is the exclusive property of
//   
//or disclosed in whole in part without prior written permission.
//   
//ALL RIGHTS RESERVED
//The entire notice above must be reproduced on all authorized
//=============================================================
//=============================================================
// 文件名称:TFTP_cli.c
// 功能描述:TFTP Client
// 维护记录:2009-5-5     V1.0
//=============================================================
#include stdio.h>
#include stdlib.h>
#include string.h>
#include unistd.h>
#include sys/socket.h>
#include netinet/in.h>
#include arpa/inet.h>
#include fcntl.h>
#include sys/types.h>
#include sys/stat.h>
//=============================================================
// 语法格式:    void main(void)
// 实现功能:    主函数,建立一个TFTP Client
// 入口参数:    无
// 出口参数:    无
//=============================================================
int main(int argc, char *argv[])
{
    int sockfd;
    struct sockaddr_in srvAddr;//创建一个服务器地址
    //char *srvIP = argv[1];
    char *srvIP ="192.168.220.198";
    unsigned short port = 69;//tftp协议默认端口为69
    //if(argc
    //{
    //    printf("argument err!\n");
    //    exit(1);
    //}
    //if(argc > 2)
    //port = atoi(argv[2]);//服务器地址和端口信息初始化
   
    bzero(&srvAddr, sizeof(srvAddr));
    srvAddr.sin_family = AF_INET;
    srvAddr.sin_port = htons(port);
    inet_pton(AF_INET, srvIP, &srvAddr.sin_addr.s_addr);//将main函数中传入的ip信息转换成网络上的big端
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);//创建一个client端socket
    if(sockfd  0)
    {
        printf("Invalid socket\n");
        exit(1);
    }
    printf("ready send data to UDP server %s:%d!\n", srvIP, port);
    //download_addr();
    int fd;
    char sendbuf[2048];
    char mode[10]="octet";
    //size_t len;
    char filename[30];
    int head_len=0;
   
    printf("input download filename:");
    fgets(filename,sizeof(filename),stdin);
    filename[strlen(filename)-1]='\0';
   
    if((fd=open(filename,O_RDWR|O_CREAT, 007))0)
    {
        printf("can not open file %s\n",filename);   
    }
   
    memset(sendbuf,0,sizeof(sendbuf));
    //------------构建一个tftp数据包头部格式;
    sendbuf[0]=0;
    sendbuf[1]=1;
    strcat(sendbuf+2,filename);
    strcat(sendbuf+strlen(filename)+3,mode);
    head_len=strlen(filename)+strlen(mode)+4;
    //printf("head_len=%d\n",head_len);
//--------------开始向服务器发送文件下载请求,并接收数据
   
    char recvbuf[1024];
    char ack_data[5];
    size_t recvlen;
    size_t len;
    len=sizeof(srvAddr);
    sendto(sockfd, sendbuf, head_len, 0, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
    while(1)
    {
        memset(ack_data,0,sizeof(ack_data));
        memset(recvbuf,0,sizeof(recvbuf));
        memset(sendbuf,0,sizeof(sendbuf));
        if((recvlen = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*)&srvAddr, &len))>0)
        {
                memcpy(ack_data,recvbuf,4);//此函数空字符照样可以拷贝
               
                if(ack_data[1]==3) //收到的是数据包
                {
                    write(fd,recvbuf+4,recvlen-4);
                    ack_data[1]=4;
                    sendto(sockfd, ack_data, 4, 0, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
                }
                else if(ack_data[1]==5) //收到的是错误信息包
        
                {
                        if(ack_data[3]==0)
                        {
                            printf("no define!\n");   
                        }
                        else if(ack_data[3]==1)
                        {
                            printf("file not found!\n");
                        }
                        else if(ack_data[3]==2)
                        {
                            printf("disk full or allocation exceeded!\n");
                        }
                        else if(ack_data[3]==4)
                        {
                            printf("illegal TFTP operation\n");   
                        }
                        else if(ack_data[3]==5)
                        {
                            printf("unkonw transfer id\n");
                        }
                        else if(ack_data[3]==6)
                        {
                            printf("file already exists!\n");   
                        }
                        else if(ack_data[3]==7)
                        {
                            printf("no such usr!\n");   
                        }
                        else if(ack_data[3]==8)
                        {
                            printf("unsupported options requested\n");
                        }
                        else
                        {
                            printf("unknow err!\n");
                        }
                }
                else
                {
                }
            
        }
        if(recvlen516)
        {
            break;
        }
        //sendbuf[len] = '\0';
        //printf("%s", sendbuf);
    }
    close(sockfd);
    return 0;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/94835/showart_1918794.html

论坛徽章:
0
2 [报告]
发表于 2013-03-15 01:15 |只看该作者
你有木有服务端的代码吖,有的话,请发邮箱:904745890@qq.com,谢谢了吖
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP