I got all of this code from the beej guide so all of the accepting can be seen from there. In the Beej’s code, he gets a message from a client, and then sends the message to all the other clients. This can be seen from this snippet here:
// handle data from a client
if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) {
// got error or connection closed by client
if (nbytes == 0) {
//handle error
}
}
else {
// we got some data from a client
for(j = 0; j <= fdmax; j++) {
// send to everyone!
if (FD_ISSET(j, &master)) {
// except the listener and ourselves
if (j != listener && j != i) {
if (send(j, buf, nbytes, 0) == -1) {
perror("send");
}
}
}
}
}
} // END handle data from client
Instead of sending the same message to all the clients, i would like to adapt it into a request/reply feature and send a reply to the same client I received data from.
here is what I have so far:
long length = 0;
string stringRead;
messagebroker broker;
read( i, &length, sizeof( length ) );
length = ntohl( length );
if(length > -1)
while ( 0 < length ) {
char buffer[1024];
int cread;
cread = read( i, buffer, min( sizeof( buffer ), length ) );
stringRead.append( buffer, cread );
length -= cread;
}
cout << "Got Message: " + stringRead << endl;
string response = broker.handleMessage(stringRead.c_str());
cout << "sending response" << response << endl;
//socket ready for writing
if (FD_ISSET(i, &master)) { //should i check to see if write_fds? I have this here
//simply because the guide has it, but i am suspicious
//it is there so we can not write to the master.
length = htonl( response.length() );
cout << "sent length" << endl;
if(send( i, &length, sizeof(length) , 0) == 0){
fprintf(stderr, "Error sending data %d\n", errno);
exit(3);
}
if(send( i, response.data(), response.length(),0 )== 0){
fprintf(stderr, "Error sending data %d\n", errno);
exit(3);
}
} //end if
I receive all data from the client at the server. I then am not sure if the problem is writing the data back on the server, or reading from the client. I assume it is writing to the client from the server. As I hinted in the comments, I think I know where I went wrong, but I have removed this if statement, and I still wasn’t able to read anything on the client side. Do I need to set a writable flag at the very beginning? Please let me know if you need anything else. Sorry this post was so long.
Just do the write. If it returns -1/EWOULDBLOCK, or a value indicating that it didn’t write the full response, then you add the FD to the writefds, and continue the write when the FD becomes writable. You normally don’t have any writefds, as FDs are normally writable, that is to say they normally have space in their socket send buffers.