I have written the following program :
/* 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],choice,howmuch;
int n=1,score1,score2;
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 numbern"); 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,&howmuch,sizeof(int))<0) {
perror("read");
exit(1);
}
if(read(sock, buf,howmuch) < 0) {
perror("read");
exit(1);
}
if(!strcmp(buf,"STOP")) break;
if(!strcmp(buf,"READY")) {
printf("Give round %d play: ",n);
choice=getchar();getchar();
switch(choice) {
case 'p':
howmuch=6;
if(write(sock,&howmuch,sizeof(int))<0){
perror("read");
exit(1);
}
if(write(sock,"PAPER",6) < 0) {
perror("read");
exit(1);
}
strcpy(move2,"PAPER");
break;
case 'r':
howmuch=5;
if(write(sock,&howmuch,sizeof(int))<0){
perror("read");
exit(1);
}
if(write(sock,"ROCK",5) < 0) {
perror("read");
exit(1);
}
strcpy(move2,"ROCK");
break;
case 's':
howmuch=9;
if(write(sock,&howmuch,sizeof(int))<0){
perror("read");
exit(1);
}
if(write(sock,"SCISSORS",9)<0) {
perror("read");
exit(1);
}
strcpy(move2,"SCISSORS");
break;
default:
printf("Invalid choicen");
}
}
bzero(move1,sizeof move1);
printf("%sn",move2) /* Here it prints as it should */
fflush(stdout);
if(read(sock,&howmuch,sizeof(int))<0) {
perror("read");
exit(1);
}
printf(""%s"n",move2); /* Here it doesn't print anything */
if(read(sock,move1,howmuch)<0) {
perror("read");
exit(1);
}
printf("Player 1:%10s Player2:%10s n",move1,move2);
n++;
}
if(read(sock,&score1,sizeof(int))<0) {
perror("read");
exit(1);
}
if(read(sock,&score2,sizeof(int))<0) {
perror("read");
exit(1);
}
printf("Score = %d - %dn",score1,score2);
if(score1==score2) printf("Nobody wonn");
else printf("You %sn",(score1>score2?"lost":"won"));
close(sock); /* Close socket */
exit(0);
}
The problem comes in for the second printf of move2.
The command :
if(read(sock,&howmuch,sizeof(int))<0) {
perror("read");
exit(1);
}
affects the variable move2.Why does this happen?
If I don't put the command above it prints move2.
What is really happening?
Thank you.That was the problem,although I still don't understand how this can affect an irrelevant variable.Anyway thanks again.
Well, because you declare "howmuch" as a "char", yet you're
reading "sizeof (int)" worth of data into it... So, you're trashing
other stack variables, in the process...
Because, it's on the stack, and located within sizeof(int) bytes
away from the variable that you overflowed... How the compiler
will lay out your variables on the stack is not always easy to
predict, but in this case, I'd say it looked like:
...
[10 bytes] move2
[1 byte] choice
[1 byte] howmuch
...
So, when you tried to read 4 bytes (presumably sizeof(int) on
your system, anyway) into the memory location of "howmuch",
you ended up also trashing "choice", and 2 bytes of "move2"...
How much does getting a small tattoo on your hip/stomach hurt?
Do anyone else have an itchy anus? ?
|