> -----Mensaje original-----
> De: grulic-dev-bounces@???
> [mailto:grulic-dev-bounces@???] En nombre de Leonardo Rios
> Enviado el: Sábado, 10 de Mayo de 2008 16:55
> Para: Lista de desarrollo de software libre
> Asunto: Re: [Grulic-dev] username en socket server
>
> 2008/5/9 Mariano Guerra <luismarianoguerra@???>:
> > On Fri, May 9, 2008 at 8:31 PM, Leonardo Rios
> <rios.lj@???> wrote:
> >> Como habia comentado al principio del mes pasado estoy
> implementado
> >> un simple chat tcp multi-thread. Según hasta donde pude llegar fue
> >> que el servidor recibe los mensajes de distintos clientes
> que mandan
> >> mensajes al servidor.
> >>
> >> Si yo tengo almacenado en el .h el nombre de usuario y el
> numero de
> >> usuario, de la forma
> >>
> >> struct struc_user { /* estructura para la comunicacion
> usada por el
> >> cliente y server */
> >>
> >> int *number_user;
> >> char username[100];
> >>
> >> } users[100];
> >>
> >> Es decir, porque ha cada cliente tengo un "Ingrese el nick "
> >> fgets(users[user].username, sizeof(users[user].username), stdin);
> >>
> >> Se puede hacer que el server muestre los username de los clientes:
> >>
> >> pedrito said --> tal cosa
> >>
> >> juanito said --> tal otra
> >>
> >>
> >> es posible esto?
> >>
> >
> > si, pero con la info que diste no puedo deducir a donde
> esta tu problema.
> > cuando llega el mensaje hay algo que identifique al usuario?
>
> Si. por el lado del server, cada cliente que se conecta
> dispongo de users[n_user].number_user , que es el resultado
> del accept (esa estructura que cite en el 1 thread). Es mas
> ... tengo estos datos que larga cuando el cliente se conecta:
>
> printf("\t\tusers[user].number_user, %d\n",
> *users[n_user].number_user);
> printf("\t\tFD Socket del cliente(net), %d\n", net);
>
> printf("\t\tDescriptor del cliente(resultado del
> accept), %d\n", (int)users[n_user].number_user); //da (-)
> printf("\t\tNumero de usuario Nº ()%d\n", n_user);
>
> Bueno, entonces la respuesta seria el descriptor del cliente ?
> Creo que cada cliente que se conecta tiene distinto numero de
> descriptor de otro cliente. Todos los clientes tienen sus
> propio numero de descriptor
>
>
Si pasas tu código te puedo dar una ayuda más concreta. De todas maneras, la
solución a tu problema no es compleja:
1. Asumo que el servidor concentra la recepción y redistribución de los
mensajes de cada cliente.
2. Cada vez que receptes un mensaje tenes que buscar en tu lista de usuarios
conectados a quién pertenece el file descriptor por el cual recibiste el
mensaje. Una vez tengas el macheo de los fd tenés el nombre de quien envió
el msg.
3. Cuando el server retransmita el msg a los demás clientes lo hará
previamente insertando el nombre del usuario autor del mismo. Voilá!
Ej. rudimentario para resolver el punto 2:
char *buscar_autor(int fd) {
int i;
for(i=0; i<100; i++)
if (users[i].number_user == fd) return users[i].username;
return NULL;
}
*Mejora*: que cada thread tenga almacenado en una variable propia el nombre
del usuario, asi te ahorras la búsqueda.
Ej. rudimentario para resolver el punto 3 de acuerdo a tu estructura:
void enviar_msg_publico(char *autor, char *mensaje, int lmsg) {
int i;
char *msg;
/* Antecedo el mensaje con el nombre del autor + " dice: "*/
msg = malloc(strlen(autor) + lmsg + 1);
strcpy(msg, autor);
strcat(msg, " dice: ");
strncat(msg, mensaje, lmsg);
lmsg += strlen(autor) + 8; // 8 = 7 del agregado por " dice: " + 1 para
el \0
msg[lmsg]=0;
/* Mando msg a todos */
for (i=0; i<100; i++)
if (users[i].number_user >= 0) /* asumo que si tiene -1 el slot no está
en uso */
write(users[i].number_user, msg, lmsg);
}
*Mejora*: tener los usuarios conectados en una lista en lugar de un array.
En el thread de cliente podrías entonces hacer lo siguiente cuando recibis
un mensaje:
...
msg_size = read(sock_cliente, msg, sizeof(msg)); // Espero mensaje del
usuario
enviar_msg_publico(buscar_autor(sock_cliente), msg, msg_size); //
retransmito a todos
...
------
Nota: toda la función es un ejemplo simplificado. Tal como te indicaron
necesitarás definir un protocolo para que el cliente sepa que lo que está
recibiendo es un mensaje a mostrar.
Otras operaciones que deberás considerar soportar en el protocolo:
- desconexiones / kicks
- información de canales
- transf. de archivos
Me parece ya te comenté en un mail anterior que tu estructura de datos tiene
problemas: estas declarando a number_user como un puntero cuando no debiera
serlo. Por eso te da negativo el printout!
Saludos,
Fernando.