send() et met() sont mélangées, (programmation d'un serveur FTP en C)
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.
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.