c - 将文件发送到远程 FTP 服务器
问题描述
我有一个任务“将文件发送到远程 FTP 服务器”。我已经编写了代码,但它无法正常工作。我创建了一个用于数据传输的套接字并尝试上传我的文件。上传文件后,我想使用 来检查服务器答案recv()
,但我的程序此时挂起,但我可以在服务器上看到我的文件。如果我recv()
从我的代码中删除,我的文件大小为 0 字节。这几天我一直在尝试解决这个问题。谁能帮我?
我正在使用这个 FTP 服务器进行测试:ftp: //speedtest.tele2.net/
int upload_file(char *filename) {
char str[256];
char buff[1024];
int getFile;
int bytes_read;
//ds - for data
sprintf(str, "CWD %s\r\n", "upload");
send(s, str, strlen(str), 0);
get_server_answer();
switch_to_passive_mode();
sprintf(str, "TYPE I\r\n");
send(s, str, strlen(str), 0);
get_server_answer();
sprintf(str, "STOR %s\r\n", filename);
send(s, str, strlen(str), 0);
get_server_answer();
getFile = open(filename, O_RDONLY, 0644);
while (1) {
bytes_read = read(getFile, buff, 1024);
if (bytes_read <= 0)
break;
send(ds, buff, bytes_read, 0);
}
char tmp[256];
recv(s, tmp, 256, MSG_WAITALL); // program hangs here
close(getFile);
close(ds);
close(s);
return 0;
}
解决方案
默认情况下,FTP 数据传输以STREAM
传输模式运行。在这种模式下,在通过套接字发送文件数据后ds
,您需要关闭ds
套接字以向服务器发出 End-Of-File 信号,然后再尝试读取服务器的答案(为什么不使用get_server_answer()
呢?)。由于您没有这样做,因此您正在等待永远不会发送的最终服务器答案。
当您删除 时recv()
,您同时关闭了ds
和s
套接字。s
通过在没有先发送命令的情况下关闭套接字QUIT
,服务器认为您的客户端在收到服务器的应答之前已经意外消失,因此它中止传输。
因此,您需要:
循环结束后关闭(但不是!),但在您
ds
阅读s
答案之前。使用该
MODE
命令将数据连接的传输模式切换到BLOCK
或COMPRESSED
模式,它不会通过关闭数据连接来发出 EOF 信号。有关详细信息,请参阅RFC 959第 3.4 节。
此外,在发送文件数据之前,您没有验证STOR
命令的初始答案是否成功(回复代码为 125 或 150)ds
推荐阅读
- c++ - boost 日志文件无法创建 sample.log 文件
- javascript - new Date(...).getTime() 和 Date.UTC(...) 之间的区别
- swift - swift不能改变uiview的宽度
- matlab - MATLAB中递归差分方程的非实根
- html - 在 SVG 中创建没有文本标签的特定符号
- javascript - 无法正确包装元素锚标记
- icons - Netbeans 11.1 用 JDK13 看起来模糊和放大
- mongodb - Docker:如何知道 mongo 是否在 Alpine/node 中使用 shell 脚本文件运行
- python - Bash 脚本找不到 Python MySQL.Connector 模块
- javascript - 从跨域 iframe 接收数据