I'm writing a chat room program that communicates over network using TCP. If user provide ip address as a command line argument, the program would attempt to connect to that address. If not, server will wait for others to connect. The server has no problem receiving whatever text message the client send. However, the client side only receives text messages from server only when it sends its own message. How do I fix that so that client side receives messages right away? This is my code
Server code:
#define MAX_CLIENTS 100
static unsigned int cli_count = 0;
static int uid = 10;
typedef struct {
struct sockaddr_in addr;
int connfd;
int uid;
char name[32];
} client_t;
client_t *clients[MAX_CLIENTS];
void queue_add(client_t *cl)
{
int i;
for(i=0;i<MAX_CLIENTS;i++)
{
if(!clients[i])
{
clients[i] = cl;
return;
}
}
}
void queue_delete(int uid)
{
int i;
for(i=0;i<MAX_CLIENTS;i++)
{
if(clients[i])
{
if(clients[i]->uid == uid)
{
clients[i] = NULL;
return;
}
}
}
}
void send_message_all(char *s)
{
int i;
for(i=0;i<MAX_CLIENTS;i++)
{
if(clients[i])
{
write(clients[i]->connfd, s, strlen(s));
}
}
}
void *hanle_client(void *arg)
{
char buff_in[256];
char buff_out[256];
int rlen;
cli_count++;
client_t *cli = (client_t *)arg;
sprintf(buff_out, "<<JOIN, HELLO %s\r\n", cli->name);
send_message_all(buff_out);
bzero(buff_in,sizeof(buff_in));
while((rlen = read( cli->connfd,buff_in,sizeof(buff_in)-1))>0)
{
sprintf(buff_out, "[%s] %s\r\n", cli->name, buff_in);
send_message_all(buff_out);
}
close(cli->connfd);
/* Delete client from queue and yeild thread */
queue_delete(cli->uid);
free(cli);
cli_count--;
pthread_detach(pthread_self());
return NULL;
}
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0, portno;
struct sockaddr_in serv_addr;
struct sockaddr_in cli_addr;
pthread_t tid;
if (argc < 2) {
printf("ERROR, no port provided\n");
exit(1);
}
//Create socket
listenfd= socket(AF_INET , SOCK_STREAM , 0);
if (listenfd == -1)
{
printf("Could not create socket");
}
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portno);
/* Bind */
if(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("Socket binding failed");
return 1;
}
/* Listen */
if(listen(listenfd, 10) < 0)
{
perror("Socket listening failed");
return 1;
}
printf("<[SERVER STARTED]>\n");
socklen_t clilen = sizeof(cli_addr);
/* Accept clients */
while( (connfd = accept(listenfd, (struct sockaddr *)&cli_addr, (socklen_t*)&clilen)))
{
/* Client settings */
client_t *cli = (client_t *)malloc(sizeof(client_t));
cli->addr = cli_addr;
cli->connfd = connfd;
cli->uid = uid++;
sprintf(cli->name, "%d", cli->uid);
/* Add client to the queue and fork thread */
queue_add(cli);
pthread_create(&tid, NULL, &hanle_client, (void*)cli);
}
}
Client code:
int main(int argc , char *argv[])
{
int sockfd, portno ;
struct sockaddr_in serv_addr;
struct hostent *server;
char message[2000],server_reply[2000];
if (argc <3)
{
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(1);
}
portno = atoi(argv[2]);
//Create socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(1);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(portno);
//Connect to remote server
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("ERROR connecting");
exit(1);
}
puts("Connected\n");
//keep communicating with server
while(1)
{
//Receive a reply from the server
bzero(server_reply,2000);
if( recv(sockfd , server_reply , 2000,0) < 0)
{
puts("recv failed");
break;
}
printf("%s", server_reply);
server_reply[0]='\0';
//Send Message to server
printf("Enter Message:");
bzero(message,2000);
fgets(message, sizeof(message),stdin);
if(send(sockfd , message , strlen(message),0) < 0)
{
puts("Send failed");
return 0;
}
}
close(sockfd);
return 0;
}