Chinaunix首页 | 论坛 | 博客
  • 博客访问: 81185
  • 博文数量: 20
  • 博客积分: 777
  • 博客等级: 军士长
  • 技术积分: 287
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-22 18:53
文章存档

2011年(1)

2009年(19)

我的朋友

分类: LINUX

2009-05-05 16:01:38

    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 < 2)

    //{

    //    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(recvlen<516)
        {
            break;
        }
        //sendbuf[len] = '\0';

        //printf("%s", sendbuf);

    }
    close(sockfd);
    return 0;
}

阅读(1591) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~