Socket programming: recv/read issue
In the server code, the problem is on this line:
msg_len = read(sockfd, msg, MAX_DATA_SIZE);
You are calling read
on sockfd
, but you need to call read
or recv
on new_sockfd
(the socket returned by accept()
). new_sockfd
is the one that's connected to the client (sockfd
is used to accept further connections - eg if another client connects).
Fantastic Fourier
RING RING RING RING RING RING RING BANANA PHONE!!! DON'T NEED QUARTERS, DON'T NEED DIMES, TO CALL A FRIEND OF MINE! DON'T NEED COMPUTER, OR TV TO HAVE A REAL GOOD TIME! I'LL CALL FOR PIZZA, I'LL CALL MY CAT! I'LL CALL WHITE HOUSE, AND HAVE A CHAT!
Updated on July 20, 2022Comments
-
Fantastic Fourier almost 2 years
EDIT: the code below has been fixed to receive and send properly AND to account for the actual bytes of messages sent annd recieved (latter thanks to EJP)
I'm programming with C in Unix.
I have server and client that are supposed to exchange msgs. While client seems to send messages fine, server doesn't receive the messages the client is sending. I've tried using
recv()
andread()
(i know they are practically the same thing but with extra flags onrecv()
) but I have no luck and I'm not really sure what the problem really is.I put
sleep(3)
in the client code after every time it sends a message but i see that once client and server are connected, server immediately closes without waiting for the incoming messages. What am i doing wrong?This is the client-side code:
#define SERVER_TCP_PORT 11112 #define MAX_DATA_SIZE 500 int main(int argc, char * argv[]) { int sockfd; char * host; char msg[MAX_DATA_SIZE];/* = "get my msg!\n";*/ int msg_len; struct hostent * hp; struct sockaddr_in client_address, server_address; printf("y halo thar\n"); // looking up from the host database if (argc == 2) host = argv[1]; else exit(1); printf("sdf\n"); hp = gethostbyname(host); if (!hp) exit(1); printf("host found\n"); // setting up address and port structure information bzero((char * ) &server_address, sizeof(server_address)); // copy zeroes into string server_address.sin_family = AF_INET; bcopy(hp->h_addr, (char *) &server_address.sin_addr, hp->h_length); server_address.sin_port = htons(SERVER_TCP_PORT); printf("set\n"); // opening up socket if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) exit(1); printf("opened\n"); // connecting if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) exit(1); printf("connected\n"); int i; for (i = 0; i < MAX_DATA_SIZE; ++i) { msg[i] = '.'; } msg[MAX_DATA_SIZE-1] = '\0'; for(i = 0; i < 11; i++) { // send message to connected socket msg_len = write(sockfd, msg, MAX_DATA_SIZE); if(msg_len < 1) printf("notsent\n"); else printf("%i bytes sent\n", msg_len); // recieve messages from connected socket msg_len = read(sockfd, msg, MAX_DATA_SIZE); if (msg_len < 1) printf("not recieved\n"); else { printf("%i bytes received\n", msg_len); printf(msg); printf("\n"); } } // close connection close(sockfd); printf("closed\n"); }
and this is the server side
#define SERVER_TCP_PORT 11112 #define MAX_DATA_SIZE 500 int main() { printf("o halo thar\n"); int sockfd, new_sockfd; int client_addr_len; char msg [MAX_DATA_SIZE]; int msg_len; char got_msg [11] = "got ur msg\0"; struct sockaddr_in server_address, client_address; // setting up address and port structure information bzero((char * ) &server_address, sizeof(server_address)); // copy zeroes into string server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(SERVER_TCP_PORT); // opening up socket if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) exit(1); printf("socket is opened\n"); // binding if (bind(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) exit(1); printf("socket is bound\n"); // listening listen(sockfd,5); printf("listening\n"); // block and wait for an incoming connection client_addr_len = sizeof(client_address); new_sockfd = accept(sockfd, (struct sockaddr *) &client_address, &client_addr_len); if (new_sockfd < 0) exit(1); printf("accepted\n"); int i; for( i = 0; i < 11; i++) { // recieve messages from connected socket printf("waiting\n"); msg_len = read(new_sockfd, msg, MAX_DATA_SIZE); if (msg_len < 1) { printf("no msg recieved\n"); } else { printf("bytes recieved: %i\n", msg_len); } // send message to connected socket msg_len = write(new_sockfd, got_msg, sizeof(got_msg)); if (msg_len < 1) printf("not sent\n"); else printf("%i bytes sent\n", msg_len); } // close connection close(sockfd); printf("socket closed. BYE! \n"); }
-
caf about 14 yearsThe message sent by the client clearly starts with a
'.'
character. -
caf about 14 yearsThere is no problem at all with the server calling
read
before the client sends anything. Theread
call will simply block until data is available. "No data recieved yet" is not an error. -
Fantastic Fourier about 14 yearsThanks that solved the problem!!! And yea, that makes a lot more sense to read from the new socket file descriptor from accept().
-
user207421 about 14 yearsYou are also ignoring the counts returned by read() and write() apart from checking them for errors. You can't do that: you must use them to determine how much data was actually read or written. You can't assume your request was fulfilled completely.
-
user207421 about 14 yearsAnd there's no need for a sleep either.
-
Fantastic Fourier about 14 yearsEJP the code now does account for actual bytes of msgs sent and received. Thanks.
-
Fantastic Fourier about 14 yearsI only added sleep() in client side to locate what the problem was but I really can't (and shouldn't have to) use sleep() since the purpose of this program is to measure packet round trips.