文档章节

FTP 编程 5 文件传输与目录切换

 流云lw
发布于 2017/07/14 10:52
字数 1057
阅读 2
收藏 0

FTP 编程 5 文件传输与目录切换


    接下来说最后一个 FTP 实现的功能点了,文件传输加上前面几篇文件介绍的功能实现组合起来基本就能实现一个 FTP 程序了,但这个只是简单的实现,和现实中能使用的还有很多要完善,但现在的时间比较紧张,没有太多时间弄了,还有好多的东西要学。所以如果各位有兴趣的话,可以自己去完善,反正要用的基本就是这些,和其他组合一下,自己摸索完善一下,比如弄个图像界面之类的。

文件传输

    本文以客户端上传文件为例,但客户端下载原理基本雷同,会其一就能写出另外一个的。文件上传的大概如下:

  • l.首先客户端向服务端发送命令说明自己要想服务端上传文件了
  • 2.服务端收到客户端的命令,在本地创建相应的文件
  • 3.客户端再向服务端发送文件的大小信息,这个信息是非常有用的,用于服务端如何判断文件传输是否完毕
  • 4.服务端收到文件大小信息,用于统计
  • 5.客服端打开相应的文件进行读取传输,用一个循环,在循环里面每次读取1024字节并传输,也就是分段传输,不是一次性读取完并传完
  • 6.服务端用一个循环接收文件信息,每次接收1024字节(与客户端同步),并统计相应的剩下的文件大小,当文件大小等于小于0时传输完毕
  • 7.客户端读取完毕,关闭文件,等待下一命令
  • 8.服务端接收完毕,关闭并保存文件,等待客户端的下一个命令

    具体的代码如下:

客户端文件上传代码


bool Client::uploadFile(std::string filePath)
{
    //打开文件
    char* workPath = _getcwd(NULL, 0);
    if (workPath == NULL) {
        std::cout << "Get current work path failed\n";
    }
    else {
        std::cout << workPath << std::endl;
    }
    std::string absolutePath = workPath;
    absolutePath += "\\";
    absolutePath += filePath;
    //使用文件I/O进行读取,这样适用于所以类型文件
    std::ifstream file(absolutePath.c_str(), std::ios_base::binary);

    if (!file) {
        std::cout << "file open failed.\n";
        return false;
    }
    else {
        std::cout << "open successful\n";
    }

    //获取文件大小
    long fileBegin = file.tellg();
    file.seekg(0, std::ios_base::end);
    long fileEnd = file.tellg();
    int fileSize = fileEnd - fileBegin;
    std::cout << "File size is " << fileEnd-fileBegin << " bytes" << std::endl;
    //将文件大小发送给服务端
    _itoa_s(fileSize, buf, 10);
    send(client, buf, 1024, 0);

    //读取文件内容
    std::cout << "开始读取文件内容" << std::endl;
    file.seekg(0, std::ios_base::beg);
    int sendCount = 0;
    while(!file.eof()) {
        memset(buf, 0, 1024);
        file.read(buf, 1024);

        int len = send(client, buf, maxSize, 0);
        if (len == SOCKET_ERROR) {
            std::cout << "Sending occur error\n";
        }

        sendCount += 1024;
        std::cout << "Send " << sendCount << "/" << fileSize << " bytes\n";
    }

    //关闭文件
    file.close();
    std::cout << "Readed file succesful\n";

    return false;
}

服务端文件上传接收代码


bool Server::receiveFile(std::string filename)
{
    //创建与上次文件名相同的文件
    std::string filePath = storePath + filename;
    std::ofstream storeFile(filePath, std::ios_base::binary);
    if (!storeFile) {
        std::cout << "Create file failed\n";
    }

    //先接收文件大小信息
    memset(buf, 0, maxSize);
    recv(server, buf, 1024, 0);
    int fileSize = atoi(buf);
    std::cout << "File's size is:" << fileSize << std::endl;

    int len = 1;
    int recvCount = 0;
    //统计文件传输剩下的大小
    int remain = fileSize;
    while (true) {
        memset(buf, 0, maxSize);
        len = recv(server, buf, 1024, 0);
        storeFile.write(buf, 1024);
        if (len == SOCKET_ERROR) {
            std::cout << "Receive occur error\n";
        }

        //如果剩下的小于等于0,说明文件传输完毕,退出循环
        remain -= 1024;
        if(remain <= 0) {
        //if (strlen(buf) == 0) {
            break;
        }

        recvCount += strlen(buf);
        std::cout << "Receive " << recvCount << " bytes\n";
    }

    //关闭并保存文件
    storeFile.close();
    std::cout << "Write file successful\n";

    return false;
}

目录切换

    这个这里大概提一下就行,其实就是传输一些文字信息而已,就socket方面而已是没有多大难道的,只要在客户端和服务端建立相应的路径变量,进行相应的同步和保存即可。获取文件目录的信息需要用到Windows的目录处理,把处理后的目录信息存到字符串中,再发送到客户端,客户端再进行处理和显示就行

最后

    FTP的技术点大概就这些,祝各位玩的愉快

源码地址

源码地址

© 著作权归作者所有

上一篇: string 详解
粉丝 1
博文 17
码字总数 30387
作品 0
六盘水
私信 提问
linux命令行中ftp的简单使用

1、启用允许root登录ftp服务器 修改/etc/vsftpd 中的ftpusers和user_list文件,均将其中的root注释掉。 2、先切换到要传输数据的目录,从这个目录移到ftp服务器的或是从ftp目录下载到这个主机...

静听天籁
2013/11/25
13
0
FTP命令大全

文件传输软件的使用格式为:FTP,若连 接成功,系统将提示用户输入用户名及口令: LOGIN: (输入合法的用户名或者“ANONMOUS”): PASSWORD: (输入合法的口令,若以“ANONMOUS”方式登录,一...

晨曦之光
2012/03/09
224
0
Vsftp简单介绍

vsftp简单介绍 一、安装与卸载 1、rpm # rpm -q vsftpd* 查询是否安装 # rpm -qi vsftpd* 查询软件包信息 # rpm -ivh vsftpd* 安装 #service vsftpd start 启动 #chkconfig vsftpd on 设置开...

王洪斌
2015/01/26
0
0
Linux/Unix服务器中gftp使用攻略(上)

【IT168 专稿】笔者曾经详细介绍了SSH服务器的安装和配置(阅读),以及Windows下的SSH客户端工具(putty、winscp等),这里结束一下在Linux 和Unix服务器中如何使用SSH客户端工具:gFTP。 ...

zhudaoyan
2014/05/09
0
0
FileZilla启用文件夹同步浏览功能听语音

在使用FTP管理工具时,在本地和远程FTP服务器之间传输文件是最常用的操作。大多数时候,FTP传输并不仅仅局限于一个目录,而是多个不同的目录,甚至多个不同层级的目录。例如,我们需要将某个...

飞翔的熊blabla
02/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
今天
6
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
今天
7
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
今天
5
0
OSChina 周日乱弹 —— 我,小小编辑,食人族酋长

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享娃娃的单曲《飘洋过海来看你》: #今日歌曲推荐# 《飘洋过海来看你》- 娃娃 手机党少年们想听歌,请使劲儿戳(这里) @宇辰OSC...

小小编辑
今天
1K
11
MongoDB系列-- SpringBoot 中对 MongoDB 的 基本操作

SpringBoot 中对 MongoDB 的 基本操作 Database 库的创建 首先 在MongoDB 操作客户端 Robo 3T 中 创建数据库: 增加用户User: 创建 Collections 集合(类似mysql 中的 表): 后面我们大部分都...

TcWong
今天
40
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部