12.20 网络编程

 实现tftp客户端下载功能

#include
#define SERPORT 69
#define N 516
#define SERIP "192.168.125.241"

//定义下载功能函数
int download(int sfd,struct sockaddr_in sin)
{
    //终端获取文件名
    char filename[20] = "";
    printf("请输入需要下载的文件名:");
    fgets(filename,20,stdin);
    filename[strlen(filename)-1] = 0;
    //发送下载请求
    char buf[N] = "";
    int size = sprintf(buf,"%c%c%s%c%s%c",0,1,filename,0,"octet",0);
    if(sendto(sfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))<0)
    {
        perror("");
        return -1;
    }
    int fd;
    int flag = 0;
    //接收发送应答包
    ssize_t recv_len;
    unsigned short num = 1;
    socklen_t addrlen = sizeof(sin);
    while(1)
    {
        bzero(buf,N);
        recv_len = recvfrom(sfd,buf,N,0,(struct sockaddr*)&sin,&addrlen);
        if(recv_len < 0)
        {
            perror("recv error");
            return -1;
        }
        if(3 == buf[1])
        {
            if(0 == flag)
            {
                //存储服务器下载下来的文件,接收数据后再创建数据
                //创建并打开文件
                fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664);
                if(fd < 0)
                {
                    perror("open error");
                    return -1;
                }
                flag = 1;    
            }
            //判断当前的快编号是否正确
            if(htons(num) == *(unsigned short*)(buf+2))
            {
                if(write(fd,buf+4,recv_len-4)<0)
                {
                    printf("fd:%d recv_len=%ld\n",fd,recv_len);
                    perror("write error");
                    break;
                }
                buf[1] = 4;
                if(sendto(sfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin)) < 0)
                {
                    perror("sendto error");
                    return -1;
                }
                //判断数据包大小是否小于516
                if(recv_len < 516)
                {
                    printf("文件下载完毕\n");
                    break;
                }
                num++;
            }
        }
        else if(5 == buf[1])
        {
            printf("ERROR:%s\n",buf+4);
            break;
        }
    }
    return 0;
}
/******************************* 主程序 *****************************************/
int main(int argc, const char *argv[])
{
    //创建套接字
    int sfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sfd < 0)
    {
        perror("");
        return -1;
    }
    //填充服务器地址结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = inet_addr(SERIP);
    sin.sin_port = htons(SERPORT);
    //终端获取操作码
    char choose;
    while(1)
    {
        system("clear");
        printf("***********************\n");
        printf("*********1.下载********\n");
        printf("*********2.上传********\n");
        printf("*********3.退出********\n");
        printf("***********************\n");
        
        scanf("%c",&choose);
        switch(choose)
        {
        case '1':
            download(sfd,sin);
            break;
    /*    case '2':
            upload(sfd,sin);
            break;*/
        case '3':
            goto END;
            break;
        default:
            printf("输入有误\n");
        }
    printf("请输入任意字符清屏:");
    }
END:
    close(sfd);

    return 0;
}
 

 

你可能感兴趣的:(网络)