-
Socket problem
I wrote the following progs:
Code:
/* prsref.c */
#include <sys/types.h> /* For sockets */
#include <sys/socket.h> /* For sockets */
#include <netinet/in.h> /* For Internet sockets */
#include <netdb.h> /* For gethostbyaddr */
#include <stdio.h>
#include <stdlib.h>
#define READ 0
#define WRITE 1
main(int argc,char** argv) {
int pid,fdp2c[2],fdc2p[2];
int port, sock, newsock, serverlen, clientlen; char buf[10];
struct sockaddr_in server, client;
struct sockaddr *serverptr, *clientptr;
struct hostent *rem;
if(argc!=3) {
printf("Usage : prsref <n> <port>\n");
exit(1);
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { /* Create socket */
perror("socket"); exit(1); }
port = atoi(argv[2]); /* Convert port number to integer */
server.sin_family = AF_INET; /* Internet domain */
server.sin_addr.s_addr = htonl(INADDR_ANY); /* My Internet address */
server.sin_port = htons(port); /* The given port */
serverptr = (struct sockaddr *) &server;
serverlen = sizeof server;
if (bind(sock, serverptr, serverlen) < 0) {/* Bind socket to address */
perror("bind"); exit(1); }
if (listen(sock, 1) < 0) { /* Listen for connections */
perror("listen"); exit(1); }
// printf("Listening for connection to port %d\n", port);
clientptr = (struct sockaddr *) &client;
clientlen = sizeof client;
if(pipe(fdp2c)==-1) {
perror("pipe");
exit(1);
}
if(pipe(fdc2p)==-1) {
perror("pipe");
exit(1);
}
if((pid=fork())==-1) {
perror("fork");
exit(1);
}
if(pid) {
int i;
char move1[10],move2[10],score[2];
close(fdp2c[READ]);
close(fdc2p[WRITE]);
printf("I am referee with PID %d waiting for game request at port %d\n",getpid(),port);
if ((newsock = accept(sock, clientptr, &clientlen)) < 0) {
perror("accept"); exit(1); } /* Accept connection */
if ((rem = gethostbyaddr((char *) &client.sin_addr.s_addr,
sizeof client.sin_addr.s_addr, /* Find client's address */
client.sin_family)) == NULL) {
perror("gethostbyaddr"); exit(1);
}
printf("Player 2 connected\n");
score[0]=score[1]=48;
for(i=1;i<=atoi(argv[1]);i++) {
write(fdp2c[WRITE],"READY",6);
write(newsock,"READY",6);
//bzero(move1,sizeof move1);
if(read(fdc2p[READ],move1,sizeof(move1))<0) {
perror("read");
exit(1);
}
if(read(newsock,move2,sizeof(move2))<0) {
perror("read");
exit(1);
}
if(write(newsock,move1,sizeof move1)<0) {
perror("write");
exit(1);
}
printf("Player 1:%10s Player2:%10s\n",move1,move2);
if((!strcmp(move1,"PAPER") && !strcmp(move2,"ROCK")) || (!strcmp(move1,"ROCK") && !strcmp(move2,"SCISSORS" )) || (!strcmp(move1,"SCISSORS") && !strcmp(move2,"PAPER")))
score[0]++;
if((!strcmp(move2,"PAPER") && !strcmp(move1,"ROCK")) || (!strcmp(move2,"ROCK") && !strcmp(move1,"SCISSORS" )) || (!strcmp(move2,"SCISSORS") && !strcmp(move1,"PAPER")))
score[1]++;
}
write(fdp2c[WRITE],"STOP",5);
write(newsock,"STOP",5);
if(write(newsock,score,sizeof score)<0) {
perror("write");
exit(1);
}
printf("Score = %c - %c\n",score[0],score[1]);
if(score[0]==score[1]) printf("Nobody won\n");
else printf("Player %d won\n",(score[0]>score[1]?1:2));
close(fdp2c[WRITE]);
close(fdc2p[READ]);
close(newsock);
}
if(!pid) {
char message[10];
close(fdp2c[WRITE]);
close(fdc2p[READ]);
printf("I am player 1 with PID %d\n",getpid());
read(fdp2c[READ],message,sizeof(message));
srand((unsigned int)getpid());
while(strcmp(message,"STOP")) {
if(!strcmp(message,"READY")) {
switch(rand()%3) {
case 0:
write(fdc2p[WRITE],"PAPER",6);
break;
case 1:
write(fdc2p[WRITE],"ROCK",5);
break;
case 2:
write(fdc2p[WRITE],"SCISSORS",9);
break;
}
}
read(fdp2c[READ],message,sizeof(message));
}
close(fdp2c[READ]);
close(fdc2p[WRITE]);
}
}
/* prs.c */
#include <sys/types.h> /* For sockets */
#include <sys/socket.h> /* For sockets */
#include <netinet/in.h> /* For Internet sockets */
#include <netdb.h> /* For gethostbyname */
#include <stdio.h> /* For I/O */
main(int argc, char *argv[]) { /* Client with Internet stream sockets */
int port, sock, serverlen; char buf[10],move1[10],move2[10],score[2],choice;
int n=1;
struct sockaddr_in server;
struct sockaddr *serverptr;
struct hostent *rem;
if (argc < 3) { /* Are server's host name and port number given? */
printf("Please give host name and port number\n"); exit(1); }
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { /* Create socket */
perror("socket"); exit(1); }
if ((rem = gethostbyname(argv[1])) == NULL) { /* Find server address */
perror("gethostbyname"); exit(1); }
port = atoi(argv[2]); /* Convert port number to integer */
server.sin_family = AF_INET; /* Internet domain */
bcopy((char *) rem -> h_addr, (char *) &server.sin_addr,
rem -> h_length);
server.sin_port = htons(port); /* Server's Internet address and port */
serverptr = (struct sockaddr *) &server;
serverlen = sizeof server;
if (connect(sock, serverptr, serverlen) < 0) { /* Request connection */
perror("connect"); exit(1); }
while(1) {
bzero(buf, sizeof buf); /* Initialize buffer */
if(read(sock, buf, sizeof buf) < 0) {
perror("write");
exit(1);
}
if(!strcmp(buf,"READY")) {
printf("Give round %d play: ",n);
choice=getchar();getchar();
switch(choice) {
case 'p':
if(write(sock,"PAPER",6) < 0) {
perror("read");
exit(1);
}
strcpy(move2,"PAPER");
break;
case 'r':
if(write(sock,"ROCK",5) < 0) {
perror("read");
exit(1);
}
strcpy(move2,"ROCK");
break;
case 's':
if(write(sock,"SCISSORS",9)<0) {
perror("read");
exit(1);
}
strcpy(move2,"SCISSORS");
break;
default:
printf("Invalid choice\n");
}
}
bzero(move1,sizeof move1);
if(read(sock,move1,sizeof move1)<0) {
perror("read");
exit(1);
}
if(!strcmp(buf,"STOP")) break;
printf("Player 1:%10s Player2:%10s\n",move1,move2);
n++;
}
bzero(score,sizeof score);
if(read(sock,score,sizeof score)<0) {// Here is the problem
perror("read");
exit(1);
}
printf("Score = %c - %c\n",score[0],score[1]);
if(score[0]==score[1]) printf("Nobody won\n");
else printf("You %s\n",(score[0]>score[1]?"lost":"won"));
close(sock); /* Close socket */
exit(0);
}
The first prog is a referee between its child and the second prog(prs) which play a game.The parent communicates through pipes with the child and through internet sockets with the second player(prs).
The prsref gets as its arguments the number of rounds and the port.The client prog,prs,takes as its arguments the server name and the port.
In every round the parent in prsref,which is the referee,sends a message "READY" to his child and to the client,prs.Then the child and the client send back their choices.The referee evaluates the score and when the game is finished sends a message "STOP" to the child and the client.
Both progs work perfectly apart from the point where the client reads the score from the referee.It doesn't read anything.
Why is that?
Thank you in advance.
-
While write(newsock,score,sizeof score) in the referee returns 2,read(sock,score,sizeof score) in prs returns zero.
Run it to see the result.It doesn't print anything on the prs for the score.It doesn't hang either.
-
I have already tried but with no result.
The right thing should be without the use of sleep().That's because when write() or read() are executed and there is no read() or write() respectively in the other side of the socket the program should block(wait) until something is read or written in the other side of the socket.But why is not working?