send() и puts() смешаны вместе (программирование FTP-сервера на C)

StackOverflow https://stackoverflow.com//questions/25038909

  •  21-12-2019
  •  | 
  •  

Вопрос

Я создаю FTP-сервер на C.На стороне клиента я использую 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:

  • Статус:Adres bepalen van localhost
  • Статус:Verbinden met [::1]:21...
  • Статус:Verbinding aangemaakt, welkomstbericht afwachten...
  • Антворд:220 JEDI FTP готов
  • Коммандос:ПОЛЬЗОВАТЕЛЬ yoda
  • Антворд:установленное соединение
  • Фут:Kan niet verbinden met server

Таким образом, вместо отправки "требуется пароль 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