I have a server-client program written in C. My problem is that I have a while loop in which I receive and send data. it happens a lot when i need my server to do other things but it just stops at recv() function and waits for data from client. How can I overcome it? I've tried this:
int waitForAnswer =1;
if((childpid = fork()) == 0){
close(socketfd);
close(fd[0]);
while(1){
if(waitForAnswer) {
receive(newSocket, buff) == 0;
parseRecvMess(buff);
}
waitForAnswer =0;
but it doesn't work. For some reason the program finishes with an exit code 1, at accepting socket with a "No Socket" error. Here is my program ;
nt main(){
int size = 256;
char buff[size];
char sbuff[size];
int n;
int reader;
int socketfd, ret;
struct sockaddr_in serverAddr;
int newSocket = -2;
struct sockaddr_in newAddr;
socklen_t addr_size;
pid_t childpid;
pocet_hracu = 0;
srand(time(NULL));
initializeLobby();
memset(buff, 0, size);
memset(sbuff, 0, size);
socketfd = socket(AF_INET,SOCK_STREAM,0);
if(socketfd < 0){
printf("\n error in socket creation");
return -1;
}
printf("\n Server socket is created\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = bind(socketfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding\n");
return -1;
}
printf("[*]Bind to port %d\n", PORT);
if(listen(socketfd, 10) == 0){
printf("Listening...\n");
}else{
printf("Error in binding\n");
}
// pipe pro komunikaci
int readpipe;
int writepipe;
int fd[2];
pipe(fd);
for (;;) {
newSocket = accept(socketfd, (struct sockaddr *) &newAddr, &addr_size);
if (newSocket < 0) {
printf("No socket\n");
exit(1);
}
// struct timeval tv;
// tv.tv_sec = 1;
// tv.tv_usec = 0;
// setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv));
// read the message from client and copy it in buffer
receive(newSocket, buff);
parseRecvMess(buff);
printf("\n%s sent: %s", user, command);
if (strncmp(" new", command, 4) == 0) {
player newPlayer;
newPlayer.name = (char *) malloc(sizeof(char) * 10); // *login must contain up to 10 characters
strcpy(newPlayer.name, user);
newPlayer.gameScore = 0;
newPlayer.roundScore = 0;
newPlayer.socket = newSocket;
// TODO vztvorit pipe pro kounikaci
// newPlayer.readpipe
// newPlayer.writepipe
addToPlayersArray(&newPlayer); //TODO player index is not increasing
addToLobby(&newPlayer);
printf("Server : %s uspesne prihlasen.\n", newPlayer.name);
}
bzero(buff, size);
printf("To client : OK\n");
strcpy(sbuff, "OK\n" );
sendMess(newSocket, sbuff, sizeof(sbuff));
int waitForAnswer =1;
if((childpid = fork()) == 0){
close(socketfd);
close(fd[0]);
while(1){
printf("MAIN->while(1)\n");
// poslouchame zpravy
//if(waitForAnswer) {
receive(newSocket, buff) == 0;
parseRecvMess(buff);
//}
waitForAnswer =0;
if(strcmp(buff,":exit") == 0){
printf("Disconnected from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
} else{
// send buff to parent
int i = findPlayerIndex();
memset(sbuff, '\0', size) ;
str str;
strcat(sbuff, "//:");
sprintf(str, "%d", i);
strcat(sbuff, str);
strcat(sbuff, ":");
strcat(sbuff, command);
strcat(sbuff, "\n");
write(fd[1], sbuff , strlen(sbuff)+1);
bzero(buff, sizeof(buff));
if (strncmp("roll", command, 4) == 0) {
//TODO
hod();
}
if (strncmp("none", command, 4) == 0) {
//TODO
}
strcpy(sbuff, "OK\n" );
write(newSocket, sbuff, strlen(sbuff));
bzero(buff, sizeof(buff));
bzero(sbuff, sizeof(sbuff));
}
}
}
close(fd[1]);
int nbytes = read(fd[0], buff, sizeof(buff));
printf("PARENT: buffer : %s\n",buff);
parseRecvMess(buff);
char *index1= (char *)malloc(sizeof(char)*10);
strcpy(index1, user);
int index = atoi(index1);
char *command1= (char *)malloc(sizeof(char)*10);
strcpy(command1, command);
//printf("PARENT - index:%d, command:%s\n", index, command );
printf("PARENT - index:%d, jmeno:%s, command:%s\n", index, players_array[index].name, command1 );
bzero(buff, sizeof(buff));
if (strncmp("room", command1, 4) == 0) {
// vlozit do mistnosti
printf("command = room\n");
command = strtok(command1," ");
command = strtok(NULL," "); // volba
printf("command(volba): + %s \n", command);
//int i = findPlayerIndex(); // find player in array based on user name
printf("player index: = %d \n", index);
//printPlayer(&players_array[i]);
volbaHry(&players_array[index], command, lobby);
//players_array[i].mist->pocet_hracu++;
printf("PARENT: array pocet hracu %d\n",players_array[index].mist->pocet_hracu);
printf("PARENT: lobby pocet hracu %d\n",lobby[0].pocet_hracu);
str str;
memset(sbuff, '\0', size);
//pokud v mistnosti jsou 2 hraci => zacina hra
if( players_array[index].mist->pocet_hracu == 2){
printf("Hra zacina ...\n");
hra(players_array[index].mist);
}
printMistnost(players_array[index].mist);
}
//players_array[index].mist = lobby[volba - 1];
// }
}
close(newSocket);
return 0;
}
and this is my receive() function:
int receive(int socket, char *buff){
int size = 256;
int reader = recv(socket, buff, size * sizeof(char), 0);
if (reader == -1) {
printf("BREAK reader == -1\n");
perror("recv()");
return(-1);
} else if (reader == 0) {
printf("BREAK reader == 0\n");
return(-2);
} else if(checkMessage(buff) == 0){
printf("ERROR: recieved message is not valid\n");
return(-3);
}
return 0;
}
if I'm not using waitForAnswer variable the program connects without any errors with the client, but at some points stops at the beginning of while waiting for another message.
You can also use ioctl() to check for data if the socket is set to non blocking
#include <sys/ioctl.h>
int status;
do{
ioctl(socketfd, FIONREAD, &status);
if( status > 0 ){
//packet waiting to be read
recv(socketfd, buff, size * sizeof(char), 0);
}
else{
// no data .. so do something else
}
} while (!must_stop);