C语言 简单的文件下载器

本文介绍了一个简易FTP服务的实现过程,包括服务器端和客户端的代码示例。该服务支持文件列表展示、文件下载及上传等功能,并详细展示了如何通过socket编程进行网络通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码中的ip地址写的都是回环测试ip,如果要在两个电脑之间,请修改代码中ip地址一行。然后服务器中的文件夹路径改为您的。
写的不好,您多担待。

服务器部分:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
char buf[64] = "\0";
DIR *dir;
struct dirent *p;
int listenfd, connfd;
int fd;
int ret;

void list()
{
    dir = opendir("/home/fs/17091/class");
    if (NULL == dir)
    {
        perror("opendir");
        exit(0);
    }
    while((p = readdir(dir)) != NULL) 
    {
        bzero(buf,sizeof(buf));
        if (0 == strncmp(".",p->d_name,1))
        continue;
        strcpy(buf,p->d_name);
        send(connfd,buf,64,0);
    }
    #if 1
    bzero(buf,sizeof(buf));
    strcpy(buf,"####");
    send(connfd,buf,4,0);
    #endif
    closedir(dir);
    return;
}

void download(char buf[])
{
    char name[64] = "/home/fs/17091/class/";
    char *p = buf+4;
    int n;
    strcat(name,p);
    name[strlen(name)-1] = '\0';
    fd = open(name,O_RDONLY);
    if (-1 == fd)
    {
        close(connfd);
        return;
    }
    while ((n = read(fd,buf,64)) > 0)
    {
        write(connfd,buf,n);
        bzero(buf,sizeof(buf));
    }
    printf("传输完毕\n");
    close(connfd);
    close(fd);
}

void upload(char buf[])
{
    char msg[64] = "\0";
    if (recv(connfd, msg, 64, 0) <= 0)
    {
        close(connfd);
        return;
    }
    else
    {
    char name[64] = "/home/fs/17091/class/";
    char *p = buf+4;
    int n;
    strcat(name,p);
    name[strlen(name)-1] = '\0';
    fd = open(name,O_WRONLY | O_CREAT | O_TRUNC,0666);
    if (-1 == fd)
    {
        strcpy(buf,"fail");
        send(connfd,buf,64,0);
        return;
    }
    while ((n = read(connfd,buf,64)) > 0)
    {
        write(fd,buf,n);
        bzero(buf,sizeof(buf));
    }
    printf("上传完毕\n");
    close(connfd);
    close(fd);

    }

}
int main(int argc, const char *argv[])
{
    struct sockaddr_in seraddr, cliaddr;
    socklen_t addrlen = sizeof(cliaddr);
    //step 1:创建套接字接口
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == listenfd)
    {
        perror("socket");
        return -1;
    }
    //step 2:绑定IP地址和端口号
    memset(&seraddr, 0, sizeof(seraddr));
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(8888);
    seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    ret = bind(listenfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
    if (-1 == ret)
    {
        perror("bind");
        return -1;
    }

    //step 3:监听连接请求
    ret = listen(listenfd, 5);
    if (-1 == ret)
    {
        perror("listen");
        return -1;
    }


    //step 4:接受连接请求
    while(1)
    {
        connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen);
        if(-1 == connfd)
        {
            perror("accept");
            return -1;
        }
        printf("accept successfully, client ip = %s, port = %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));


        while(1)
        {
            //接受数据
            bzero(buf,sizeof(buf));
            ret = recv(connfd, buf, sizeof(buf), 0);
            if (-1 == ret)
            {
                perror("read");
                return -1;
            }

            if (0 == strncmp("list",buf,4))
            {
                list();
                break; 
            }
            else if (0 == strncmp("get",buf,3))
            {
                download(buf);
                break; 
            }
            else if (0 == strncmp("put",buf,3))
            {
                upload(buf);
                break; 
            }
            else
            break;
        }
        close(connfd);

    }
    close(listenfd);
    return 0;
}

客户端部分:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
char buf[64] = "\0";
int fd;
int ret;

int init_net()
{
    struct sockaddr_in seraddr;
    int connfd;
    //step 1: 创建套接字接口
    connfd = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == connfd)
    {
        perror("socket");
        return -1;
    }
    //step 2: 发起连接请求
    memset(&seraddr, 0, sizeof(seraddr));
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(8888);
    seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    ret = connect(connfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
    if(-1 == ret)
    {
        perror("connect");
        return -1;
    }
    return connfd;

}
void help()
{
    printf("hlep:显示客户端所有命令和说明\n");
    printf("list:显示服务器端可下载文件列表\n");
    printf("get+空格+文件名:下载文件\n");
    printf("put+空格+文件名:上传文件\n");
    printf("quit:退出客户端\n");
}

void list()
{
    int connfd;
    connfd = init_net();
    strcpy(buf,"list");
    ret = send(connfd, buf, sizeof(buf), 0);    
    if(-1 == ret)
    {
        perror("send");
        return;
    }
    while (1)
    {
        if ((recv(connfd,buf,64,0) > 0))
        {
            if (strncmp("####",buf,4) != 0) 
            printf("%s\n",buf);
            else
            break;
        }
    }
    close(connfd);
    return;
}

void download(char buf[])
{
    int connfd;
    char msg[64] = "\0";
    connfd = init_net();
    send(connfd,buf,64,0);
    if (recv(connfd,msg,64,0) <= 0)
    {
        printf("没有这个文件,无法下载\n");
        close(connfd);
        return;
    }
    else
    {
        int n;
        char *p = buf+4;
        char name[64] = "/home/fs/17091/play/download/";
        strcat(name,p);
        name[strlen(name)-1] = '\0';
        fd = open(name,O_WRONLY | O_CREAT | O_TRUNC,0666);
        if (-1 == fd)
        {
            perror("open");
            return;
        }
        while ((n = read(connfd,buf,64)) > 0)
        {
            write(fd,buf,n);
            bzero(buf,sizeof(buf));
        }
        printf("下载完成\n");
        close(fd);
        close(connfd);
        return;
    }
}

void upload(char buf[])
{
    int connfd;
    connfd = init_net();
    send(connfd,buf,64,0);
    int n;
    char *p = buf+4;
    char name[64] = "/home/fs/17091/play/download/";
    strcat(name,p);
    name[strlen(name)-1] = '\0';
    fd = open(name,O_RDONLY);
    if (-1 == fd)
    {
        printf("没有这个文件,无法上传\n");
        close(connfd);
        return;
    }
    while ((n = read(fd,buf,64)) > 0)
    {
        write(connfd,buf,n);
        bzero(buf,sizeof(buf));
    }
    printf("上传完成\n");
    close(fd);
    close(connfd);
    return;

}
int main(int argc, const char *argv[])
{

    while (1)
    {

        system("clear");
        printf("请输入选项,输入'help'查看帮助\n");
        printf("input>>");
        fgets(buf,sizeof(buf),stdin);
        if (0 == strncmp("help",buf,4))
        {
            help();
            printf("输入Enter键继续\n");
            getchar();
            continue;
        }
        if (0 == strncmp("list",buf,4))
        {
            list();
            printf("输入Enter键继续\n");
            getchar();
            continue;
        }
        else if (0 == strncmp("get",buf,3))
        {
            printf("开始下载\n");
            download(buf);
            printf("输入Enter键继续\n");
            getchar();
            continue;
        }
        else if (0 == strncmp("put",buf,3))
        {
            printf("开始上传\n");
            upload(buf);
            printf("输入Enter键继续\n");
            getchar();
            continue;
        }
        else if (0 == strncmp("quit",buf,4))
        {
            printf("欢迎下次使用,祝您生活愉快\n");
            break;
        }
        else
        {
            printf("输入有误,请输入Enter键继续\n");
            getchar();
            continue;
        }
    }



    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值