免费注册 查看新帖 |

Chinaunix

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

TFTP协议实现 [复制链接]

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

                   依据TFTP协议的规定,实现通过TFTP来实现文件的传输功能。[color="#CC3333"]TFTP Server:实现功能:实现TFTP服务器,可以让用户下载文件命令:          tftps [color="#009999"]rootdir(请求的文件路径)实现思路:        监听69端口        接收到数据后,fork子进程服务该客户端        分析客户端的请求报文,检查是否有扩展参数        如果有扩展参数,则回应OACK,并等待客户端对OACK做回应        启动传输数据        文件传输结束后子进程退出
tftps.c
int main(int argc,char **argv)
{
    int server_sockfd,client_sockfd;
    int server_len,client_len;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;
    char recv_buf[516] = {};
    char send_buf[516] = {};
    char recv_cmd[4] = {};
    int byte;
    int n = 0;
    int pid,fd;
    server_sockfd
= socket(AF_INET,SOCK_DGRAM,0);
    bzero(&server_address,sizeof(server_address));
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = inet_addr("192.168.220.59");
[color="#0000CC"]//我的PC机IP地址

    server_address.sin_port = htons(69);
    server_len = sizeof(server_address);
    bind(server_sockfd,(struct sockaddr                                *)&server_address,server_len);
   
if((byte = recvfrom(server_sockfd,recv_buf,516,0,(struct        sockaddr *)&client_address,sizeof(struct sockaddr))) == -1)
    {
        perror("recvfrom");
        exit(0);
    }
[color="#0000CC"]//创建一个进程来分析收到的报文信息

    if((pid = fork()) == 0)
    {
        if(recv_buf[1] == 1)  //为下载文件请求
        {
            printf("this is a read request:\n");
            if((fd = open(recv_buf[2],O_RDONLY))  0)
            {
                perror("open");
                exit(0);
            }
[color="#0000CC"]

            while(1)
            {
                recvfrom(server_sockfd,recv_cmd,4,0,(struct sockaddr *)&client_address,sizeof(struct sockaddr));
                read(fd,send_buf+4,sizeof(send_buf+4));
[color="#0000CC"]//将文件内容读入数据区

                send_buf[1] = 3;
[color="#0000CC"]//构造报文

                if((byte = sendto(server_sockfd,send_buf,516,0,(struct sockaddr *)&client_address,sizeof(struct sockaddr))) == 516)
                {
                    sendto(server_sockfd,send_buf,4,0,(struct sockaddr *)&client_address,sizeof(struct sockaddr));
                    send_buf[3]++;
                }
[color="#0000CC"]//TFTP每次发送512个字节,附带四个字节的报文信息,小于516时就代表文件传输完毕

                else
                    exit(0);
            }
        }
        if (recv_buf[1] == 2) //为上传文件请求
        {
            printf("this is a write request:\n");
            if((fd = open(recv_buf[2],O_RDWR|O_CREAT))  0)
            {
                perror("open");
                exit(0);
            }
            while(1)
            {
                recvfrom(server_sockfd,recv_cmd,4,0,(struct sockaddr *)&client_address,sizeof(struct sockaddr));
                recvfrom(server_sockfd,recv_buf,512,0,(struct sockaddr *)&client_address,sizeof(struct sockaddr));
                write(fd,send_buf+4,sizeof(send_buf+4));
                send_buf[1] = 3;
                if((byte = sendto(server_sockfd,send_buf,516,0,(struct sockaddr *)&client_address,sizeof(struct sockaddr))) == 516)
                {
                    sendto(server_sockfd,send_buf,4,0,(struct sockaddr *)&client_address,sizeof(struct sockaddr));
                    send_buf[3]++;
                }
                else
                    exit(0);
            }
        }
        close(fd);
    }
    else
        return 0;
}
        
            
TFTP Client:实现功能:通过tftp下载文件命   令:tftpc ip file实现思路:        构造请求报文,送至服务器        等待服务器回应        分析服务器回应        循环接收数据,直到接收到的数据包小于标准数据包tftpc.c
#include sys/types.h>
#include sys/socket.h>
#include stdio.h>
#include sys/un.h>
#include unistd.h>
#include stdlib.h>
#include string.h>
#include arpa/inet.h>
#include netinet/in.h>
#include fcntl.h>
int main(int argc,char **argv)
{
    int sockfd;
    struct sockaddr_in server;
    char read_cmd[100] = {};
    char buf[516]="";
    char *str;
    int addrlen = sizeof(server);
    int fd,rew,recv,read_num,send_num;
    int n = 0,num;
    char filename[100] = {};
   
    if(argc == 1)
    {
        printf("ERROR:please input a filename:\n");
        exit(0);
    }
    else if(argc == 2)
    {
        strcpy(filename,argv[1]);
    }
    bzero(&server, sizeof(struct sockaddr_in));
    server.sin_family = AF_INET;
    server.sin_port = htons(69);
    server.sin_addr.s_addr = inet_addr("192.168.220.59");
   
    printf("please input read?write:1 or 2:  ");
    scanf("%d",&num);
    rew = sprintf(read_cmd,"%c%c%s%c%s%c",0,num,filename,0,"octet",0);
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockfd  0)
    {
        perror("Invalid socket");
        exit(1);
    }
   
sendto(sockfd, read_cmd, rew, 0, (struct sockaddr*)&server, sizeof(struct sockaddr));
    if((fd = open(filename, O_RDWR|O_CREAT))0)   
    {        
        perror("open");
        exit(1);
    }
   
if (num == 1)
    {
        num = 0;
        do{
            bzero(buf,sizeof(buf));
            recv = recvfrom(sockfd, buf, 516, 0, (struct sockaddr*)&server, &addrlen);   
            write(fd, buf+4, 512);
            if(n == 255)
            {
                num++;
                n = -1;
            }
            rew = sprintf(read_cmd,"%c%c%c%c",0,4,num,++n);
            sendto(sockfd, read_cmd, rew, 0, (struct sockaddr*)&server, sizeof(struct sockaddr));
        }while(recv == 516);
    }
   
    if( num == 2)
    {
        do{
            bzero(buf,sizeof(buf));
            recvfrom(sockfd, buf, 4, 0, (struct sockaddr*)&server, &addrlen);        
            buf[1] = 3;
            if((unsigned char)buf[3]==255)
            {
                buf[2]++;
            }
            buf[3]++;
            read_num = read(fd,buf+4,512);
            printf("%d\n",send_num);
            send_num = sendto(sockfd, buf, read_num+4, 0, (struct sockaddr*)&server, sizeof(struct sockaddr));
        }while(read_num==512);
    }                    
    close(fd);
    return 0;
}
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/103431/showart_2046719.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP