我正在尝试从服务器下载文件;客户端和服务器都是Linux,但是ssh_scp_read()返回错误的整数。根据文档,该函数最多可写入65536个字节,但在文件为37980时仅读取16384个字节,但这不是我的主要关注;在这16384个字节的末尾附近,它开始用NULL垃圾填充缓冲区,然后将其写入文件。

递归目录的创建工作正常;问题是下载大于16384字节的文件。在这一点上,我将使用sftp而不是scp,但是我想知道我在做什么错。

这是功能代码:

int get(ssh_session gno_ses,ssh_scp scp)
{
    int rc;
    int size, permissions;
    char *buff, *filename, path[PATH_MAX];

    while(1)
    {
        rc = ssh_scp_pull_request(scp);
        switch (rc)
        {
            // cases [...]
            case SSH_SCP_REQUEST_NEWFILE:
                size = ssh_scp_request_get_size(scp);
                printf("Size is %d\n",size);
                filename = strdup(ssh_scp_request_get_filename(scp));
                permissions = ssh_scp_request_get_permissions(scp);

                FILE *file;
                file = fopen(filename, "w+");
                if (!file)
                {
                    ssh_scp_deny_request(scp,"Unable to open");
                    fprintf(stderr, " %s: %s\n", filename, strerror(errno));
                    fclose(file);
                    break;
                }

                buff = malloc(size);
                printf("Size of buffer is %d\n", size);
                if (!buff)
                {
                    fprintf(stderr, "\nBuff memory allocation error.\n");
                    return SSH_ERROR;
                }

                if( ssh_scp_accept_request(scp) != SSH_OK)
                {
                    fprintf(stderr, "Error accepting request: %s\n", ssh_get_error(gno_ses));
                    break;
                }

                do
                {
                    rc = ssh_scp_read(scp, buff, size);
                    if (rc == SSH_ERROR)
                    {
                        fprintf(stderr, "Error receiving file data: %s\n", ssh_get_error(gno_ses));
                        break;
                    }
                    if (fwrite(buff, 1, size, file) != size)
                    {
                        perror("Error at writting to file: ");
                        break;
                    }
                    printf("ssh_scp_read got %d\n",rc);
                } while (rc != 0);

                fclose(file);
                free(filename);
                free(buff);
                break;
        }
    }
    return SSH_OK;
}


这是输出:

Size is 37980
Size of buffer is 37980
ssh_scp_read got 16384
ssh_scp_read got 16384
ssh_scp_read got 5212
Error receiving file data: ssh_scp_read called under invalid state


任何输入将不胜感激。

最佳答案

问题是,我确实在写size字节时,实际上scp_scp_read()报告了它的读取少于该字节:

rc = ssh_scp_read(scp, buff, size);
fwrite(buff, 1, size, file)


解决方法是只写rc个字节:

            int len_loop = size;
            int len;
            do
            {
                rc = ssh_scp_read(scp, buff, size);
                if (rc == SSH_ERROR || rc < 0)
                {
                    fprintf(stderr, "Error receiving file data: %s\n", ssh_get_error(gno_ses));
                    break;
                }
                else if (!rc)
                {
                    break;
                }
                len = fwrite(buff, 1, rc, file);
                if (len != rc)
                {
                    perror("Error at writting to file: ");
                    break;
                }
                printf("ssh_scp_read got %d\n",rc);
                len_loop -= rc;
            } while(len_loop);

10-04 13:27