我正在用 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 数据包指定了字符串的大小。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top