send() 和 put() 混合在一起,(用 C 语言编程 FTP 服务器)
题
我正在用 C 语言制作一个 FTP 服务器。在客户端,我使用 FileZilla。到目前为止,我的代码仅包含握手部分。
我遇到的问题是我为终端打印的字符串被发送到 FileZilla。我的问题是如何将这两个分开,我尝试了一些方法,但没有一个给出正确的结果。
这只是我的代码的一部分,但对于我的问题来说,这是有用的部分:
while (FOREVER){
addr_size = sizeof their_addr;
newfd = accept(listener, (struct sockaddr*) &their_addr, &addr_size);
if (newfd == -1){
perror("accept");
continue;
}
if ((send(newfd, "220 JEDI FTP is ready", 50, 0)) <= 0)
perror("error sending");
puts("connection established");
puts("waiting for user & connection");
while (!login){
// username
if (!user){
if ((recv(newfd, buffer, BUFFCON, 0)) <= 0){
puts("error receiving username");
}
else{
if (strstr(buffer, "USER") != NULL){
if (strstr(buffer, name) != NULL){
send(newfd, "331 password required", 50, 0);
puts("username correct");
user = 1;
}
else{
puts("username incorrect");
send(newfd, "430 username incorrect", 50, 0);
}//else
}//if
}//else
}//if user
这是 FileZilla 中的输出:
- 地位:地址 bepalen van 本地主机
- 地位:韦尔宾登遇见了 [::1]:21...
- 地位:令人信服的 aangemaakt,welkomstbericht afwachten...
- 反词:220 JEDI FTP 已准备就绪
- 突击队:用户尤达
- 反词:连接已建立
- 福特:Kan niet verbinden met 服务器
因此,它不会发送“需要 331 密码”,而是发送“已建立连接”
希望你能帮我解决这个问题,非常感谢。
解决方案
问题是你的 len
参数为 send
太大了。 send
没有空终止字符串的概念;它仅适用于原始字节序列。所以调用 send(newfd, "220 JEDI FTP is ready", 50, 0)
发送字符串 "220 JEDI FTP is ready"
, ,然后无论发生什么,都会出现在内存中。从技术上来说,这是 未定义的行为, ,所以字面上 任何事物 可能会发生(通常是段错误)。在您的情况下,因为常量文字字符串通常按顺序存储在内存中, send
正在读取给定的字符串,然后读取其后的不同字符串。
你想做的是 仅有的 发送确切的字符串(顺便说一句,需要 CR-LF 序列 \r\n
在每个命令之后)。不多也不少。您可以实施一个 sends
函数发送一个字符串,如下所示:
ssize_t sends(int fd, const char *str)
{
size_t len = strlen(str);
return send(fd, str, len, 0);
}
另请注意,发送的数据确实 不是 包括空终止符,因为 TCP 数据包指定了字符串的大小。
不隶属于 StackOverflow