Pregunta

Estoy haciendo un servidor FTP en C.En el lado del cliente estoy usando FileZilla.Mi código hasta el momento sólo contiene el protocolo de la parte.

El problema que tengo es que las cadenas puedo imprimir para el terminal se envían a FileZilla.Mi pregunta es ¿cómo puedo mantener a estos dos separados, yo he probado un par de cosas, pero ninguno de ellos dar el resultado correcto.

Esta es sólo una parte de mi código, pero mi pregunta es esta la parte útil:

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

Y este es el resultado de FileZilla:

  • Estado:Adres bepalen van localhost
  • Estado:Verbinden cumplirse [::1]:21...
  • Estado:Verbinding aangemaakt, welkomstbericht afwachten...
  • Antwoord:220 JEDI FTP está listo
  • Comando:USUARIO yoda
  • Antwoord:la conexión se ha establecido
  • Cuatro:Kan niet verbinden se reunió servidor

Así que en lugar de enviar "331 contraseña necesaria" envía "conexión establecida"

Espero que me puedan ayudar con esto, muchas Gracias.

¿Fue útil?

Solución

El problema es que su len parámetro para send es demasiado grande. send no tiene el concepto de cadenas terminadas en nulos;solo funciona con las secuencias de bytes.Por lo que la llamada send(newfd, "220 JEDI FTP is ready", 50, 0) envía la cadena "220 JEDI FTP is ready", y luego lo que sucede en la memoria después de ella.Técnicamente, esto es un comportamiento indefinido, por lo que, literalmente nada podría suceder (generalmente una violación de segmento).En su caso, debido a la constante de las cadenas literales son generalmente almacenados secuencialmente en la memoria, send es la lectura de la cadena de texto y, a continuación, leer una cadena diferente después de ella.

Lo que quiero hacer es sólo enviar la cadena exacta (que, por cierto, de las necesidades de la CR-LF secuencia \r\n después de cada comando).No más, no menos.Se puede implementar un sends función para enviar una cadena así:

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

También tenga en cuenta que los datos enviados no no incluir el carácter terminador nulo, debido a que el paquete TCP especifica el tamaño de la cadena.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top