Question

Je suis en train de faire un serveur FTP en C.Du côté client, je suis en utilisant FileZilla.Mon code jusqu'à présent ne contient que l'établissement de la liaison de la partie.

Le problème que j'ai, c'est que les cordes j'ai imprimer pour le terminal sont envoyés à FileZilla.Ma question est comment puis-je garder ces deux séparés, j'ai essayé plusieurs choses, mais aucun d'entre eux donne le résultat correct.

Ce n'est qu'une partie de mon code, mais pour ma question, est-ce la partie utile:

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

Et c'est la sortie dans FileZilla:

  • Statut:Adres bepalen van localhost
  • Statut:Verbinden rencontré [::1]:21...
  • Statut:Verbinding aangemaakt, welkomstbericht afwachten...
  • Antwoord:220 JEDI FTP est prêt
  • Commando:L'UTILISATEUR yoda
  • Antwoord:la connexion est établie
  • Fout:Kan niet verbinden rencontré serveur

Donc, au lieu de les envoyer "331 mot de passe requis" il envoie "connexion établie"

J'espère que vous pourrez m'aider, Merci beaucoup.

Était-ce utile?

La solution

Le problème, c'est que votre len paramètre pour send est trop grande. send n'a pas de concept de nul de chaînes;il ne fonctionne qu'avec les premières séquences d'octets.Donc, l'appel send(newfd, "220 JEDI FTP is ready", 50, 0) envoie la chaîne "220 JEDI FTP is ready", et puis quoi qu'il arrive à venir à la mémoire d'après elle.Techniquement, c'est un comportement indéfini, donc, littéralement rien pourrait se produire (généralement une erreur de segmentation).Dans votre cas, parce que les constantes chaînes de caractères littérales sont généralement stockées de manière séquentielle dans la mémoire, send c'est la lecture de la chaîne, puis la lecture d'une chaîne de caractère après.

Ce que vous voulez faire est seulement envoyer la chaîne exacte (ce qui, par la manière, a besoin de la CR-LF séquence \r\n après chaque commande).Pas plus, pas moins.Vous pouvez mettre en œuvre une sends fonction pour envoyer une chaîne de caractères comme suit:

ssize_t sends(int fd, const char *str)
{
    size_t len = strlen(str);
    return send(fd, str, len, 0);
}

Notez également que les données envoyées ne pas inclure la valeur null-terminator, car le paquet TCP spécifie la taille de la chaîne.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top