Programming chat client, need some help (sockets & threads)
Ok so here's the thing, I need to create a program that simulates a chat client, there's a server to which any number of clients can connect to and send messages from one client to another.
Both the client and the server are pretty much done, one of the clients sends a message to another through the server and the message gets to the destinated client, BUT only after I've inputed an action, like requesting some type of information from the server (like asking for a list of the clients currently connected to the server).
I tried creating a pthread to execute the readerMSG method so the client is constantly reading from the server, the problem is the read method kinda gets stuck, and so does the rest of the program, threaded or not.
Any ideas on what I can do so I can keep the client constantly "listening" for anything from the server?
This is the code for the client, I don't think the problem is with the server, so I'll only post if necessary.
Code:
#include "data.h"
// Declaracion de funciones que se van utilizar
void error(string);
bool login(int,char *);
void execute(int,string);
void sendMessage(int,char**);
void readMessage(int);
void *readerMSG(void*);
void *interfaceCliente(void*);
int main(int argc, char *argv[]){
//string command;
// Datos de la coneccion
int socketC; // El socket del cliente
struct sockaddr_in serverChat; // Direccion al server
char bufferC[BUFFER_SIZE];
// Este thread se encarga de leer los mensajes
pthread_t reader;
// Se verifica que si los numeros de parametros estan correctos
if(argc != 5){
fprintf(stderr,"USAGE: cliente <username> <cliente's port> <server ip> <server's port>\n");
exit(1);
}
// Se crea el socket a utilizar y se verifica si se pudo
socketC = socket(PF_INET, SOCK_STREAM, 0);
if(socketC < 0){
error("Failed to create socket");
}
// Se realiza la coneccion a servidor
// se crea el ente que va manejar la direccion del servidor
memset(&serverChat,0,sizeof(serverChat));
serverChat.sin_family = AF_INET; // Usa dominio internet
serverChat.sin_addr.s_addr = inet_addr(argv[3]); //Direccion ip del server
serverChat.sin_port = htons(atoi(argv[4])); // Puerto del server
// Se realiza la coneccion
if(connect(socketC,(struct sockaddr *)&serverChat,sizeof(serverChat)) < 0){
error("ERROR: failed to connect with server");
}
if(!login(socketC,argv[1])){
error("ERROR: failed to log to server");
}
//pthread_create(&reader,NULL,readerMSG,(void*)socketC);
//readMessage(socketC);
interfaceCliente((void*)socketC);
return 0;
}
void *interfaceCliente(void *socketFV){
string command;
int socketC = (int)socketFV;
while(1){
//readMessage(socketC);
cout<<"HLCHAT: ";
getline(cin,command);
execute(socketC,command);
}
}
void *readerMSG(void *socketFV){
readMessage((int)socketFV);
}
void error(string msg){
perror(msg.c_str());
exit(1);
}
bool login(int socketF,char *username){
// Donde el servidor va constestar a usuario
char wbuffer[BUFFER_SIZE];
bzero(wbuffer,BUFFER_SIZE);
string message = LOGIN_WORD;
// Se crea el mensaje que se enviara al servidor
message = message + " " + username;
// Se escribe al servidor
if(write(socketF,getArray(message),message.length())<0){
error("ERROR: failed to write to socket");
}
// Se obtiene la respuesta de servidor
if(read(socketF,wbuffer,BUFFER_SIZE) <0){
error("ERROR: failed to read from socket");
}
// Se analiza la respuesta del servidor
char** response = theLexer(wbuffer);
if(strcmp(response[0],ACCEPT_WORD) == 0){
cout<<"You have loged successful"<<endl;
return true;
}
else{
cout<<"You have not loged successful"<<endl<<wbuffer<<endl;
return false;
}
}
void execute(int sockectF, string command){
string message;
char cBuffer[BUFFER_SIZE];
bzero(cBuffer,BUFFER_SIZE);
// Se escanea el comando
char** tokens = theLexer(getArray(command));
if(strcmp(tokens[0],LIST_WORD) == 0){
message = LIST_WORD;
if(write(sockectF,getArray(message),message.length()) < 0)
error("ERROR: Failed to write to socket");
if(read(sockectF,cBuffer,BUFFER_SIZE)< 0)
error("ERROR: Failed to read from socket");
cout<<cBuffer<<endl;
}
// se envia un mensaje
else{
sendMessage(sockectF,tokens);
}
}
void readMessage(int socketF){
char** tokens2;
char cBuffer[BUFFER_SIZE];
bzero(cBuffer,BUFFER_SIZE);
int cont;
//while(1){
bzero(cBuffer,BUFFER_SIZE);
if(read(socketF,cBuffer,BUFFER_SIZE) <0){
error("ERROR: failed to read from socket");
}
tokens2 = theLexer(cBuffer);
if(strcmp(tokens2[0],GET_MESSAGE_WORD)){
cont = 0;
while(tokens2[cont] != NULL){
if(cont == 0);
else if(cont == 3)
cout<<"\b";
else
cout<<tokens2[cont]<<" ";
}
cout<<"\b\b";
}
//}
}
/* Se encarga de enviar un mensaje al servidor */
void sendMessage(int sockectF,char** tokens){
// Mensaje que recibira del servidor
char cBuffer[BUFFER_SIZE];
bzero(cBuffer,BUFFER_SIZE);
// se crea el mensaje que enviara al servidor
string message = MESSAGE_WORD;
message += " ";
message += tokens[0];
message += " $";
int cont = 1;
while(tokens[cont] != NULL){
message += tokens[cont];
message += " ";
cont++;
}
message += "\b$";
if(write(sockectF,getArray(message),message.length()) < 0)
error("ERROR: Failed to write to socket");
if(read(sockectF,cBuffer,BUFFER_SIZE)< 0)
error("ERROR: Failed to read from socket");
cout<<cBuffer<<endl;
}