如何使用libssh和sftp在C/C++中复制文件

Rap*_*ner 6 c c++ ssh sftp libssh

我在这里发帖是因为我需要一些与libssh相关的代码的帮助.

在这里阅读了所有官方文档 ,但是如果有人可以点亮我我会很高兴,我仍然不明白我需要做的事情.

其实我想将文件从客户端复制到远程服务器,但我不明白如何使用图书馆libssh和libssh功能SFTP做到这一点.

情况是:ssh会话打开,sftp会话也是打开的,我可以创建一个文件,并使用lib ssh的集成功能从客户端写入服务器.

我没有找到一种简单的方法将文件从客户端复制到服务器,使用简单的函数,如sftp_transfer(sourceFile(如c:\ my document\hello world.txt),RemoteFile(/ home/user/hello world.txt) ),对(读(写)))

根据我从教程中理解的内容,它首先在远程位置(服务器)创建一个文件,然后用这行代码打开这个文件:

file = sftp_open(sftp, "/home/helloworld.txt",access_type,1);
Run Code Online (Sandbox Code Playgroud)

之后,在服务器上创建文件,然后使用缓冲区写入此创建的文件:

const char *helloworld = "Hello, World!\n";
int length = strlen(helloworld);
nwritten = sftp_write(file, helloworld, length);
Run Code Online (Sandbox Code Playgroud)

我现在的问题是,如果我有一个文件,例如.doc文件,我想将该文件从c:\ mydocument\document.doc传输/上传到远程服务器/home/user/document.doc远程我该怎么办?用这种方法吗?

如何将此文件放入sftp_write()函数中以像示例函数中的helloworld一样发送它?

我可能在编程上不够理解,但我真的试图理解它并且我坚持使用它.

在此先感谢您的帮助

请参阅下面我用于测试的代码示例:

// Set variable for the communication
      char buffer[256];
      unsigned int nbytes;

        //create a file to send by SFTP
        int access_type = O_WRONLY | O_CREAT | O_TRUNC;
        const char *helloworld = "Hello, World!\n";
        int length = strlen(helloworld);

        //Open a SFTP session
        sftp = sftp_new(my_ssh_session);
        if (sftp == NULL)
        {
            fprintf(stderr, "Error allocating SFTP session: %s\n",
            ssh_get_error(my_ssh_session));
            return SSH_ERROR;
        }
        // Initialize the SFTP session
        rc = sftp_init(sftp);
        if (rc != SSH_OK)
        {
            fprintf(stderr, "Error initializing SFTP session: %s.\n",
            sftp_get_error(sftp));
            sftp_free(sftp);
            return rc;
         }

        //Open the file into the remote side
        file = sftp_open(sftp, "/home/helloworld.txt",access_type,1);
        if (file == NULL)
        {
            fprintf(stderr, "Can't open file for writing: %s\n",ssh_get_error(my_ssh_session));
            return SSH_ERROR;
        }

        //Write the file created with what's into the buffer
        nwritten = sftp_write(file, helloworld, length);
        if (nwritten != length)
        {
            fprintf(stderr, "Can't write data to file: %s\n",
            ssh_get_error(my_ssh_session));
            sftp_close(file);
            return SSH_ERROR;
        }

` 
Run Code Online (Sandbox Code Playgroud)

Reu*_*ais 5

以通常的方式打开文件(使用 C++ 的fstream或 C 的stdio.h),将其内容读取到缓冲区,并将缓冲区传递给sftp_write.

像这样的东西:

ifstream fin("file.doc", ios::binary);
if (fin) {
  fin.seekg(0, ios::end);
  ios::pos_type bufsize = fin.tellg();   // get file size in bytes
  fin.seekg(0);                          // rewind to beginning of file

  std::vector<char> buf(bufsize);        // allocate buffer
  fin.read(buf.data(), bufsize);         // read file contents into buffer

  sftp_write(file, buf.data(), bufsize); // write buffer to remote file
}
Run Code Online (Sandbox Code Playgroud)

请注意,这是一个非常简单的实现。您可能应该以追加模式打开远程文件,然后以块的形式写入数据,而不是发送单个巨大的数据块。


Mar*_*ryl 5

以下示例ifstream在循环中使用以避免将整个文件加载到内存中(接受的答案正在做什么):

ifstream fin("C:\\myfile.zip", ios::binary);

while (fin)
{
    constexpr size_t max_xfer_buf_size = 10240
    char buffer[max_xfer_buf_size];
    fin.read(buffer, sizeof(buffer));
    if (fin.gcount() > 0)
    {
        ssize_t nwritten = sftp_write(NULL, buffer, fin.gcount());
        if (nwritten != fin.gcount())
        {
            fprintf(
              stderr, "Error writing to file: %s\n", ssh_get_error(ssh_session));
            sftp_close(file);
            return 1;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)