[Problema] Conexión Sockets

Iniciado por farresito, 31 Marzo 2011, 23:37 PM

0 Miembros y 4 Visitantes están viendo este tema.

farresito

Acabo de empezar con Sockets y generalmente entiendo todo, pero no logro arreglar un error en accept(), aun habiendo leído otros ejemplos. Agradecería muchísimo a quien pudiese echarme una mano, pues llevo un tiempo y no se que pasa. El ejemplo está ordenadito, así que no debería ser un problema entenderlo.

Código (cpp) [Seleccionar]
#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdio.h>


using namespace std;

int main()
{
    //Estructuras
    struct sockaddr_in servidor;
    struct sockaddr_in cliente;

    //Otras variables
    int desc_cliente, desc_servidor;
    int puerto = 3550, max_conex = 2, size;

    //Funcinn SOCKET
    if (desc_servidor = socket(AF_INET, SOCK_STREAM, 0) == -1)
    {
        printf("Hubo un error en SOCKET");
        exit (-1);
    }

    //Estructura SOCKADDR_IN
    servidor.sin_family = AF_INET;
    servidor.sin_port = htons(puerto);
    servidor.sin_addr.s_addr = INADDR_ANY;
    memset(servidor.sin_zero, 0, 8);

    //Funcion BIND
    if (bind(desc_servidor, (struct sockaddr*) &servidor, sizeof(struct sockaddr)) == -1)
    {
        printf("Error en BIND");
        exit(-1);
    }

    //Funcion listen
    if (listen(desc_servidor, max_conex) == -1)
    {
        printf("Error en LISTEN");
        exit(-1);
    }

    //Bucle + accept
    while (1)
    {
        size = sizeof(struct sockaddr_in);
        if (cliente = accept(desc_servidor, (struct sockaddr *) &cliente, &size))
        {
            printf("Error en ACCEPT");
            exit(-1);
        }

        printf("Tienes una conexión de %s \n", inet_ntoa(cliente.sin_addr));

        send(desc_cliente, "Bienvenido al servidor \n", 22, 0);
        close (desc_cliente);
    }

}


Los errores que me marca son los siguientes:
Código (txt) [Seleccionar]
/home/farresito/Documentos/project/main.cpp||In function 'int main()':|
/home/farresito/Documentos/project/main.cpp|25|warning: suggest parentheses around assignment used as truth value|
/home/farresito/Documentos/project/main.cpp|55|error: invalid conversion from 'int*' to 'socklen_t*'|
/home/farresito/Documentos/project/main.cpp|55|error:   initializing argument 3 of 'int accept(int, sockaddr*, socklen_t*)'|
/home/farresito/Documentos/project/main.cpp|55|error: no match for 'operator=' in 'cliente = accept(desc_servidor, ((sockaddr*)(& cliente)), ((socklen_t*)(& size)))'|
/usr/include/netinet/in.h|226|note: candidates are: sockaddr_in& sockaddr_in::operator=(const sockaddr_in&)|
||=== Build finished: 3 errors, 1 warnings ===|


Otra cosilla, porque se hace el bucle? Para que hasta que no haga un accept no termine? No acabo de entenderlo...

Un abrazo de antemano. Muchas gracias por el soporte que me habéis dado hasta ahora.

Saludos

poitier

El error es este:


        if (cliente = accept(desc_servidor, (struct sockaddr *) &cliente, &size))


Cliente lo has puesto tipo struct sockaddr_in. La llamada al sistema accept, devuelve el descriptor de socket asociado a la nueva conexión del cliente. Por lo tanto debe de ser un int. Para que te funcione tienes que poner desc_cliente.

En cuanto al bucle, haces un bucle infinito while(1). En dicho bucle aceptas conexiones entrantes, creas un socket asociadas a dichas conexiones (con accept) y envías el mensaje al cliente. Cierras la conexión con el cliente (close desc_cliente) y vuelta empezar.

Un saludo

farresito

Gracias por responder, poitier. He hecho el cambio de cliente por desc_cliente en la función accept y me marca prácticamente los mismos errores. La verdad no se que pasa.

Te entendí bien, y hice el cambio para que lo que retornase la función accept se fuera a la variable descriptora de cliente.

Un abrazo. Aprecio de verdad vuestra ayuda :-*

poitier

Cita de: farresito en  1 Abril 2011, 14:37 PM
Gracias por responder, poitier. He hecho el cambio de cliente por desc_cliente en la función accept y me marca prácticamente los mismos errores. La verdad no se que pasa.

Te entendí bien, y hice el cambio para que lo que retornase la función accept se fuera a la variable descriptora de cliente.

Un abrazo. Aprecio de verdad vuestra ayuda :-*

Perdona por la tardanza, farresito, se me fue el melón y se me olvidó responder.

Veamos, hay varias cosas que tienes que corregir:


  • Estás programando en C, por lo que el #include <iostream> y el using namespace std, te sobra. Eso es para c++.
  • Tienes que poner #include <unistd.h> para la función close
  • El resto de warnings no son importantes

Mira a ver si te funciona así, sino, pregunta y lo miramos.

Un saludo y suerte

Garfield07

#4
Código (cpp) [Seleccionar]

#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdio.h>


using namespace std;

int main()
{
   struct sockaddr_in servidor;
   struct sockaddr_in cliente;

   //Otras variables
   int desc_cliente, desc_servidor;
   int puerto = 3550, max_conex = 2, size;

   //Funcinn SOCKET
   if ((desc_servidor = socket(AF_INET, SOCK_STREAM, 0)) == -1)
   {
       printf("Hubo un error en SOCKET");
       exit (-1);
   }

   //Estructura SOCKADDR_IN
   servidor.sin_family = AF_INET;
   servidor.sin_port = htons(puerto);
   servidor.sin_addr.s_addr = INADDR_ANY;
   memset(servidor.sin_zero, 0, 8);

   //Funcion BIND
   if (bind(desc_servidor, (struct sockaddr*) &servidor, sizeof(struct sockaddr)) == -1)
   {
       printf("Error en BIND");
       exit(-1);
   }

   //Funcion listen
   if (listen(desc_servidor, max_conex) == -1)
   {
       printf("Error en LISTEN");
       exit(-1);
   }

   //Bucle + accept
   while (1)
   {
       size = sizeof(struct sockaddr_in);
       if ((cliente = accept(desc_servidor, (struct sockaddr *) &cliente, &size))==-1)
       {
           printf("Error en ACCEPT");
           exit(-1);
       }

       printf("Tienes una conexión de %s \n", inet_ntoa(cliente.sin_addr));

       send(desc_cliente, "Bienvenido al servidor \n", 22, 0);
       close (desc_cliente);
   }
}


Me dice que tengo un parásito en un puñado de líneas, y el código se debería mejorar mucho, pero ahí queda. Te pongo otro código, el tuyo es muy largo y enrevesado. 100% casero ;)

#include <stdio.h>          //Funciones basicas
#include <string.h>         //StrCmp
#include <stdlib.h>         //Exit y otras
#include <arpa/inet.h>      //struct sockaddr_in
#include <sys/socket.h>     //Socket, Connect...

struct sockaddr_in host, client;    //Declaraciones
int a=sizeof (struct sockaddr);
int newsock;
int sockfd;
int main (int argc, char *argv [])
{
   printf ("Code 1.0  By Sagrini (2010)\n");
   if ((sockfd=socket (2, 1, 0))==-1)
   {
       printf ("Error abriendo socket...\n\n");
       return 1;
   }
   host.sin_port=htons(31337);
   host.sin_family=AF_INET;
   host.sin_addr.s_addr=0;
   memset (host.sin_zero, 0, 8);
   if(bind(sockfd,(struct sockaddr*)&host,sizeof(host))==-1)
   {
       printf ("Error haciendo binding...\n\n");
       return 1;
   }
   if(listen(sockfd,5)==-1)
   {
       printf ("Error escuchando...\n\n");
       return 1;
   }
   while (1)
   {
   if((newsock=accept(sockfd, (struct sockaddr*)&client, &a))==-1)
   {
       printf ("Error esperando conectando...\n\n");
       return 1;
   }
   printf ("Got connection from %s:%d\n", inet_ntoa (client.sin_addr), ntohs (client.sin_port));
   send (newsock, "Hola!\r\n", 7, 0);
   close (newsock);
   }
   close (sockfd);
   return 0;
}


* Quiero cambiar el mundo, pero estoy seguro de que no me darían el código fuente.
* No estoy tratando de destruir a Microsoft. Ese será tan solo un efecto colateral no intencionado.
* Si compila esta bien, si arranca es perfecto.

¡Wiki elhacker.net!
Un saludo

poitier

#5
Cita de: Sagrini en  4 Abril 2011, 21:15 PM
Me dice que tengo un parásito en un puñado de líneas, y el código se debería mejorar mucho, pero ahí queda. Te pongo otro código, el tuyo es muy largo y enrevesado. 100% casero ;)

#include <stdio.h>          //Funciones basicas
#include <string.h>         //StrCmp
#include <stdlib.h>         //Exit y otras
#include <arpa/inet.h>      //struct sockaddr_in
#include <sys/socket.h>     //Socket, Connect...

struct sockaddr_in host, client;    //Declaraciones
int a=sizeof (struct sockaddr);
int newsock;
int sockfd;
int main (int argc, char *argv [])
{
   printf ("Code 1.0  By Sagrini (2010)\n");
   if ((sockfd=socket (2, 1, 0))==1)
   {
       printf ("Error abriendo socket...\n\n");
       return 1;
   }
   host.sin_port=htons(31337);
   host.sin_family=AF_INET;
   host.sin_addr.s_addr=0;
   memset (host.sin_zero, 0, 8);
   if(bind(sockfd,(struct sockaddr*)&host,sizeof(host))==1)
   {
       printf ("Error haciendo binding...\n\n");
       return 1;
   }
   if(listen(sockfd,5)==1)
   {
       printf ("Error escuchando...\n\n");
       return 1;
   }
   while (1)
   {
   if((newsock=accept(sockfd, (struct sockaddr*)&client, &a))==1)
   {
       printf ("Error esperando conectando...\n\n");
       return 1;
   }
   printf ("Got connection from %s:%d\n", inet_ntoa (client.sin_addr), ntohs (client.sin_port));
   send (newsock, "Hola!\r\n", 7, 0);
   close (newsock);
   }
   close (sockfd);
   return 0;
}


Pues yo veo el mismo código que el de farresito, eso sí, con menos espacios  :P

Tienes varios errores en las funciones socket, bind, accept...
El error es cuando devuelve -1, no 1.


Te recomiendo que uses las constantes simbólicas AF_INET, SOCK_STREAM, etc. y no los valores asociados.

Garfield07

#6
Cita de: poitier en  4 Abril 2011, 22:12 PM
Pues yo veo el mismo código que el de farresito, eso sí, con menos espacios  :P

Tienes varios errores en las funciones socket, bind, accept...
El error es cuando devuelve -1, no 1.

Te recomiendo que uses las constantes simbólicas AF_INET, SOCK_STREAM, etc. y no los valores asociados.

No, el mío corre bien. El error del primer código es que necesita poner entre paréntesis asignaciones. Y se lo puse porque esperaba que le ayudase  ;)
Luego... cierto, me has pillado. Fallo mío, o más bien del teclado xD. Nunca me acostumbraré a estas cosas xD. Ahora modifico, gracias.
Y... me ahorra espacio y memoria. Y sé que son cada uno, pero es pura pereza  :)

PS: Un detalle, haz siempre caso de todos los warnings. Te ahorrará problemas  ;D
Sagrini


* Quiero cambiar el mundo, pero estoy seguro de que no me darían el código fuente.
* No estoy tratando de destruir a Microsoft. Ese será tan solo un efecto colateral no intencionado.
* Si compila esta bien, si arranca es perfecto.

¡Wiki elhacker.net!
Un saludo

poitier

Cita de: Sagrini en  5 Abril 2011, 21:13 PM
No, el mío corre bien. El error del primer código es que necesita poner entre paréntesis asignaciones. El mío corre y el suyo no.
Luego... cierto, me has pillado. Fallo mío, o más bien del teclado xD. Nunca me acostumbraré a estas cosas...
Y... me ahorra espacio y memoria. Y sé que son cada uno, pero gracias de todos modos.  :¬¬

PD: Y si me vas a recomendar tú eso yo te recomendaré que hagas caso de todos los warnings.

Lo que te dije te lo has tomado a mal, no pretendía ofenderte, sino ayudarte. Pero no te preocupes, que no va a volver a pasar. Tu llevas razón, gracías por tu recomendación ;)