Servidor de chat
De SolarSockets C++ Sockets C++
Es un servidor de chat relativamente simple, pero que permite recibir múltiples conexiones, hacerlo a mano implica aun mas tiempo que el cliente, con SolarSockets y muy poco código obtendrás los mismos resultados. Ademas ya no tendrás que preocuparte por la capa de comunicaciones, nosotros lo hacemos por ti, en cambio puedes dedicar mas tiempo a la lógica de tu proyecto.
Para complicarlo un poco vamos a implementar 3 comando PING, QUIT e INFO. Ademas vamos a poner código para filtrar los cliente, por ejemplo si el cliente tiene IP 191.168.0.20 entonces rechazamos la conexión.
Nota: Para probar el servidor también se puede utilizar como cliente un cliente Telnet. Usado de la siguiente forma:
telnet localhost 9999
Descarga
Copia y Pega
// Solar-OpenSource.Org (c) #include <SolarSockets/SolarSockets.h> bool EventoRecibe (string Cadena, int ID, ssServer* Server) { /* ---- Inicia Modificacion para Telnet Windows ---- */ // Telnet de Windows envia caracter por caracter cuando presionamos una // tecla. // pero un solo caracter no nos sirve de nada, por lo que tenemos que // concatenar los caracteres recibidos, uno por uno, y si nos llega un // return, entonces ya tendremos una cadena completa. // Variable estatica, que servira para almacenar los datos hasta que // llegue un "/r/n" static string Comandos = ""; // Concatenamos Comandos = Comandos + Cadena; int fin; string CadenaCompleta; // Buscamos en return fin = Comandos.find("\r\n"); // Si no lo encontramos no hacemos nada, en espera de que lleguen // mas datos. if (fin == string::npos) return true; // Si encontramos un Fin de linea o return, cortamos hasta // encontrar el return CadenaCompleta = Comandos.substr(0, fin+2); // Y el resto lo dejamos para la siguente. Comandos = Comandos.substr(fin+2, 999); // NOTA: Hay un error conceptual, dado que estamos usando la // misma variable Comandos para todos los clientes conectados, y // puede ocurrir que recibamos fragmentos enviados por clientes // diferentes. Lo ideal es que tengamos una variable Comandos // para cada Cliente, es decir una variable diferente para // cada ID. Una forma de hacerlo es crear un array de variables // Comando y usar una u otra para cada cliente. /* ---- Fin de la Modificacion para Telnet ---- */ string Mensaje = ""; if (CadenaCompleta == "PING\r\n") { // Contestamos con un Ping Server->Send ("PONG\r\n", ID); } else if (CadenaCompleta == "QUIT\r\n") { // Si nos envian la cadena QUIT lo desconectamos Server->Close (ID); } else if (CadenaCompleta == "INFO\r\n") { // Un cliente esta pidiendo informacion char CountChar[20]; // Convertimos de INT a CONST CHAR*</span> sprintf(CountChar,"%i",Server->Count()); Mensaje = string("Numero de Clientes: ") + CountChar + "\r\n"; Server->Send (Mensaje, ID); } else { // Convertimos de INT a CONST CHAR* char IDchar[20]; sprintf(IDchar,"%i",ID); // Concatenamos todo para formar la respuesta Mensaje = Mensaje + "[Cliente:" + IDchar + " dice] " + CadenaCompleta + "\r\n"; cout << Mensaje; // Enviamos el mismo mensaje a todo los clientes, pero no al que lo envio. Server->SendMulticast(Mensaje, ID); } return true; } void EventoConectado (int ID, ssServer* Server) { // Filtramos los cliente que queremos aceptar. if (Server->getIP(ID) != "191.168.0.20") { // Aceptamos al nuevo cliente unicamente si su IP no es la 191.168.0.20 Server->Accept(); cout << "Cliente Conectado IP: " << Server->getIP(ID) << endl; } else { cout << "Cliente Rechazado IP: " << Server->getIP(ID) << endl; } } int main (void) { // Declaramos un servidor ssServer ServerZeru; // Le decimod a que funcion hay que llamar cuando ocurra el evento Recive ServerZeru.setOnDataArrival(EventoRecibe); ServerZeru.setOnConnect(EventoConectado); // Lo ponemos a escuchar por el puerto 9999. ServerZeru.Listen(9999); cout << "Servidor escuchando por el puerto 9999" << endl; // Para que no se cierre inmediatamente. int X; cin >> X; return 0; }


