Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: mester en 20 Junio 2016, 14:35 pm



Título: Chat con listas en C
Publicado por: mester en 20 Junio 2016, 14:35 pm
Hola.

Estoy haciendo un chat con listas en C y tengo algunos problemas a la hora de insertar los datos y tal, me da violaciones de segmento cuando quiero acceder a los datos y tal.

La estructura es esta:
Código
  1. typedef struct _ConnectedHosts {
  2.  int socket;
  3.  char *Alias;
  4.  char *ipAddr;
  5.  struct _ConnectedHosts *Next;
  6. } ConnectedHosts, *PConnectedHosts;

Para inicializar una estructura o crearla, utilizo esta funcion:
Código
  1. PConnectedHosts CreateClient(int socket) {
  2.  int addrlen;
  3.  char *ipAddr = (char *)calloc(INET_ADDRSTRLEN, sizeof(char));
  4.  struct sockaddr_in ConnectedAddr;
  5.  struct _ConnectedHosts *cHosts = (PConnectedHosts)malloc(sizeof(ConnectedHosts));
  6.  
  7.  addrlen = sizeof(ConnectedAddr);
  8.  if(getpeername(socket, (struct sockaddr *)&ConnectedAddr, &addrlen) < 0) {
  9.    return NULL;
  10.  }
  11.  
  12.  inet_ntop(AF_INET, &ConnectedAddr.sin_addr, ipAddr, INET_ADDRSTRLEN);
  13.  
  14.  cHosts->socket = socket;
  15.  cHosts->ipAddr = ipAddr;
  16.  cHosts->Alias = (char *)calloc(ALIASLEN, sizeof(char));
  17.  cHosts->Next = NULL;
  18.  
  19.  return cHosts;
  20. }

Para añadir una estructura nueva a la lista uso esta otra:
Código
  1. void AddClient(PConnectedHosts RemoteAddr, PConnectedHosts MainAddr) {
  2.  PConnectedHosts aux = MainAddr;
  3.  
  4.  if(MainAddr == NULL) {
  5.    MainAddr = RemoteAddr;
  6.  }
  7.  else {
  8.    while(aux->Next != NULL) {
  9.      aux = aux->Next;
  10.    }
  11.  
  12.    aux->Next = RemoteAddr;
  13.  }
  14. }

Para eliminar alguna estructura de la lista uso esta:
Código
  1. int DeleteClient(PConnectedHosts DeleteAddr, PConnectedHosts MainAddr) {
  2.  if(MainAddr == NULL || DeleteAddr == NULL) {
  3.    return 1;
  4.  }
  5.  
  6.  PConnectedHosts bAux;
  7.  PConnectedHosts aux = MainAddr;
  8.  PConnectedHosts aAux;
  9.  
  10.  while(aux != DeleteAddr) {
  11.    bAux = aux;
  12.    aux = aux->Next;
  13.    aAux = aux->Next;
  14.  }
  15.  
  16.  close(aux->socket);
  17.  free(aux->Alias);
  18.  free(aux->ipAddr);
  19.  free(aux);
  20.  
  21.  bAux->Next = aAux;
  22.  return 0;
  23. }

Y luego utilizo esta funcion para saber qué cliente ha enviado los datos (ya que se trata de un chat):
Código
  1. PConnectedHosts whatsClient(int socket, PConnectedHosts MainAddr) {
  2.  PConnectedHosts aux = MainAddr;
  3.  
  4.  if(aux != NULL) {
  5.    while(aux->Next != NULL && aux->socket != socket) {
  6.      aux = aux->Next;
  7.    }
  8.  }
  9.  
  10.  return aux;
  11. }

Y aquí está el codigo del servidor:
Código
  1. #include "WDestChat.h"
  2.  
  3. int main() {
  4.  int i, aux, max, cSocket, lSocket;
  5.  char Buffer[1025];
  6.  struct sockaddr_in ServerAddr, ClientAddr;
  7.  PConnectedHosts auxHosts = NULL;
  8.  PConnectedHosts cHosts = NULL;
  9.  fd_set master, temp;
  10.  
  11.  lSocket = CreateListenSocket(PORT, MAX, &ServerAddr);
  12.  if(lSocket < 0) {
  13.    PrintError("Error creating socket");
  14.    return 1;
  15.  }
  16.  
  17.  max = lSocket + 1;
  18.  FD_SET(lSocket, &temp);
  19.  
  20.  while(1) {
  21.    master = temp;
  22.    if(select(max, &master, NULL, NULL, NULL) < 0) {
  23.      PrintError("Error receiving information");
  24.      return 1;
  25.    }
  26.  
  27.    for(i = 0; i <= max; i++) {
  28.      if(FD_ISSET(i, &master)) {
  29.        if(i == lSocket) {
  30.          cSocket = AcceptClient(lSocket, &ClientAddr);
  31.          if(cSocket < 0) {
  32.            PrintError("Error accepting client");
  33.          }
  34.          else {
  35.            if(max < cSocket) {
  36.              max = cSocket + 1;
  37.            }
  38.            /* Creating client list */
  39.            auxHosts = CreateClient(cSocket);
  40.            if(auxHosts == NULL) {
  41.              PrintError("Error creating client list");
  42.            }
  43.            /* receiving the alias */
  44.            recv(cSocket, auxHosts->Alias, 15, 0);
  45.            /* adding client to structure */
  46.            AddClient(auxHosts, cHosts);
  47.            /* adding client to socket array */
  48.            FD_SET(cSocket, &temp);
  49.  
  50.            printf("New client connected\n");
  51.          }
  52.        }
  53.        else {
  54.          aux = recv(i, Buffer, 1024, 0);
  55.          if(aux == 0) {
  56.            printf("%d socket was closed the connection\n", i);
  57.            FD_CLR(i, &temp);
  58.            auxHosts = whatsClient(i, cHosts);
  59.            DeleteClient(auxHosts, cHosts);
  60.          }
  61.          else if(aux > 0) {
  62.            printf("%s\n", Buffer);
  63.            for(aux = 0; aux < max; aux++) {
  64.              if(aux == i || aux == lSocket) {
  65.                continue;
  66.              }
  67.              else {
  68.                auxHosts = whatsClient(aux, cHosts);
  69.                send(aux, auxHosts->Alias, 15, 0);
  70.                send(aux, Buffer, 1024, 0);
  71.              }
  72.            }
  73.            memset(Buffer, '\0', sizeof(Buffer));
  74.          }
  75.        }
  76.      }
  77.    }
  78.  }
  79.  close(lSocket);
  80.  return 0;
  81. }

Segun GDB da error en la línea 69, es decir, al intentar acceder a la posicion de memoria que contiene el alias. Me gustaría saber qué estoy haciendo mal. Al parecer a la hora de acceder a los datos accedo a posiciones erróneas.


Título: Re: Chat con listas en C
Publicado por: AlbertoBSD en 20 Junio 2016, 14:56 pm
Hola!

No he terminado de comprender a fondo el programa pero solo para estar seguro de unas cuantas cosas.

Trata de imprimir el valor (Direccion apuntada de) de auxHosts antes del error, solo para ver que si este inicializado.

Donde inicializas max (minusculas) No veo donde este y la otra es < o <= en el for es que no veo donde este inicializado y ni sobre que cosa estes iterando.

Saludos.


Título: Re: Chat con listas en C
Publicado por: mester en 20 Junio 2016, 15:00 pm
Trata de imprimir el valor (Direccion apuntada de) de auxHosts antes del error, solo para ver que si este inicializado.

Me imprime esto:
Código:
(nil)
Violación de segmento (`core' generado)

Citar
Donde inicializas max (minusculas) No veo donde este y la otra es < o <= en el for es que no veo donde este inicializado y ni sobre que cosa estes iterando.

Saludos.

¿Qué? xd


Título: Re: Chat con listas en C
Publicado por: AlbertoBSD en 20 Junio 2016, 15:15 pm
Ahi esta el problema al momento que tratas de acceder a auxHosts no esta inicializado. Actualmente apunta a NULL.

Tienes que ver por que no se inicializo.

Saludos!


Título: Re: Chat con listas en C
Publicado por: mester en 21 Junio 2016, 15:34 pm
Ahi esta el problema al momento que tratas de acceder a auxHosts no esta inicializado. Actualmente apunta a NULL.

Tienes que ver por que no se inicializo.

Saludos!

Ya lo he solucionado. Simplemente debía reservar memoria para cHosts, por un problema en la funcion AddClient. Bueno, ya está, gracias.