使用 libssh 复制文件
Copying a file with libssh
我正在尝试编写一个简单的程序(玩具示例),将文件从远程主机复制到本地计算机。
当我尝试复制一个 txt 文件时它有效,但不适用于 mp4 等文件。
这是我的代码,基本上是教程中的部分拼接而成:https://pastebin.com/0FPrmeDx
这是错误发生的地方:
int scp_receive(ssh_session session, ssh_scp scp)
{
int rc;
int size, mode;
char *filename, *buffer;
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_NEWFILE)
{
fprintf(stderr, "Error receiving information about file: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
size = ssh_scp_request_get_size(scp);
filename = strdup(ssh_scp_request_get_filename(scp));
mode = ssh_scp_request_get_permissions(scp);
printf("Receiving file %s, size %d, permisssions 0%o\n",
filename, size, mode);
free(filename);
buffer = malloc(size);
if (buffer == NULL)
{
fprintf(stderr, "Memory allocation error\n");
return SSH_ERROR;
}
ssh_scp_accept_request(scp);
rc = ssh_scp_read(scp, buffer, size);
if (rc == SSH_ERROR)
{
fprintf(stderr, "Error receiving file data: %s\n",
ssh_get_error(session));
free(buffer);
return rc;
}
printf("Done!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
int filedesc = open("/home/user/video.mp4", O_WRONLY | O_CREAT);
if (filedesc < 0) {
return -1;
}
write(filedesc, buffer, size);
free(buffer);
close(filedesc);
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_EOF)
{
fprintf(stderr, "Unexpected request: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
return SSH_OK;
}
代码引发错误:
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_EOF)
{
fprintf(stderr, "Unexpected request: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
这是我得到的错误:
Unexpected request: ssh_scp_pull_request called under invalid state
我想弄清楚,但我无法取得任何进展。
更新 1:
复制文件的大小与源文件的大小完全相同,无论是 txt 还是 mp4 文件。但是,复制的文件似乎大部分是空的......
复制时,权限由 -rwxr-xr-x
更改为 --wxr-----
。
更新 2:
看来文件大小在这里起着主要作用。可以毫无问题地复制非常小的文件 (10-15kb)。较大的文件不会被复制并产生上述错误...
您不能指望 ssh_scp_read()
会在一次调用中读取全部数据。您必须迭代,直到没有更多数据可供读取:
int r = 0;
while (r < size) {
int st = ssh_scp_read(scp, buffer+r, size-r);
r += st;
}
现在,对 ssh_scp_pull_request(scp)
的后续调用应该会成功。
我正在尝试编写一个简单的程序(玩具示例),将文件从远程主机复制到本地计算机。
当我尝试复制一个 txt 文件时它有效,但不适用于 mp4 等文件。
这是我的代码,基本上是教程中的部分拼接而成:https://pastebin.com/0FPrmeDx
这是错误发生的地方:
int scp_receive(ssh_session session, ssh_scp scp)
{
int rc;
int size, mode;
char *filename, *buffer;
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_NEWFILE)
{
fprintf(stderr, "Error receiving information about file: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
size = ssh_scp_request_get_size(scp);
filename = strdup(ssh_scp_request_get_filename(scp));
mode = ssh_scp_request_get_permissions(scp);
printf("Receiving file %s, size %d, permisssions 0%o\n",
filename, size, mode);
free(filename);
buffer = malloc(size);
if (buffer == NULL)
{
fprintf(stderr, "Memory allocation error\n");
return SSH_ERROR;
}
ssh_scp_accept_request(scp);
rc = ssh_scp_read(scp, buffer, size);
if (rc == SSH_ERROR)
{
fprintf(stderr, "Error receiving file data: %s\n",
ssh_get_error(session));
free(buffer);
return rc;
}
printf("Done!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
int filedesc = open("/home/user/video.mp4", O_WRONLY | O_CREAT);
if (filedesc < 0) {
return -1;
}
write(filedesc, buffer, size);
free(buffer);
close(filedesc);
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_EOF)
{
fprintf(stderr, "Unexpected request: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
return SSH_OK;
}
代码引发错误:
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_EOF)
{
fprintf(stderr, "Unexpected request: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
这是我得到的错误:
Unexpected request: ssh_scp_pull_request called under invalid state
我想弄清楚,但我无法取得任何进展。
更新 1:
复制文件的大小与源文件的大小完全相同,无论是 txt 还是 mp4 文件。但是,复制的文件似乎大部分是空的......
复制时,权限由 -rwxr-xr-x
更改为 --wxr-----
。
更新 2:
看来文件大小在这里起着主要作用。可以毫无问题地复制非常小的文件 (10-15kb)。较大的文件不会被复制并产生上述错误...
您不能指望 ssh_scp_read()
会在一次调用中读取全部数据。您必须迭代,直到没有更多数据可供读取:
int r = 0;
while (r < size) {
int st = ssh_scp_read(scp, buffer+r, size-r);
r += st;
}
现在,对 ssh_scp_pull_request(scp)
的后续调用应该会成功。