I'm new to this forum, so I'm sorry if my question is not correctly asked. I'll try to be as clear as possible.
I'm trying to code two programs (client.c and server.c, using TCP sockets) in Linux, with the following behavior:
Client sends messages to Server that contain commands (ls, mkdir, etc) to be run by Server.
Server runs these commands, and sends program output (stdout) back to Client.
Client prints the recieved program output.
So far, I have this:
server.c:
/*After creating socket with socket(), binding to address and port,
putting in listening mode and accepting connection*/
dup2(sock_client,1); //redirect stdout
while(1){
recv(sock_client,buf,MAX_MSG_LENGTH,0);
/*If the message recieved was END_STRING, exit this loop*/
if (strncmp(buf, END_STRING, MAX_MSG_LENGTH) == 0)
break;
system(buf);
}
client.c:
/*After creating socket and connecting*/
while(fgets(buf,MAX_MSG_LENGTH,stdin)){
send(sock,buf,MAX_MSG_LENGTH,0);
if (!strncmp(buf,END_STRING,MAX_MSG_LENGTH)){
/*If the message recieved was END_STRING, exit this loop*/
break;
}
read(sock,buf,MAX_MSG_LENGTH); //read stdout from program
printf("%s\n",buf);
}
My problem is that, if a command has a long output, there's some "garbage" left from it when showing the output of the next commands, so I was wondering if there was a way to flush the socket (apparently not, based on my google research), or maybe to accomplish the expected server-client behavior in some other way.
Thank you!
EDIT:
Ok, I've finished the client. Here's the code:
client.c:
/* After creating socket and connecting*/
while(fgets(buf,MAX_MSG_LENGTH,stdin)){
send(sock,buf,MAX_MSG_LENGTH,0);
if (!strncmp(buf,END_STRING,MAX_MSG_LENGTH)){
/*If the message recieved was END_STRING, exit this loop*/
break;
}
while(1){
read_size = read(sock,buf,MAX_MSG_LENGTH);
/*Print read_size characters from buf*/
printf("%.*s\n", read_size, buf);
if (read_size < MAX_MSG_LENGTH){
/*Keep on reading until read_size < MAX_MSG_LENGTH, then exit this loop*/
break;
}
}
/*Clear buffer, just in case*/
for (i = 0; i < MAX_MSG_LENGTH; i++){
buf[i] = 0;
}
Just as a comment, this program will not work properly if the command sent to the server doesn't have any standard output (for example, mkdir new_directory
), since, in this case, read()
will leave the client permanently blocked, causing the server to never recieve the next command to be run or the END_STRING
message to leave the program from the client. You could probably fix this by using a non-blocking socket and using select()
to read from socket, just like synther suggested. Additionally, in the server, after the system(buf);
line, you should add fflush(0)
, which will flush all the buffers (including the socket, which could be useful if the command send by the client has a really short output).
Thanks a lot!