user2176271
user2176271

Reputation: 33

Linux C TCP Socket client/server with redirected output application

Let me start out by saying that this is a homework assignment for an operating systems class and I am not a programmer, especially not in C. I've been at this for a week now and I am simply stuck and I need help. I have to create TCP client and server applications where linux commands are typed into the client, executed on the server and the output is redirected back to the client. I understand the concept and I have it 90+% working. Commands like "ls", "ls -lpq", "cat somefile", "man somecommand" all work fine. Where I run into trouble is with commands that do not return any information like "mkdir newdir" (if the directory already exists it works fine because I get a response). This is all new to me but it seems to me that my problem is with the servers recv command blocking because there is no information to receive. I don't know how to get past this, I have been working this one issue for a week. I'm running out of time and I also have to implement file upload and download and I don't know where to begin there but I can't even start to work on that until I get past this issue.

Thanks

    // this is where I think the problem is
    while ((rcvd_bytes = recv(sock_fd, recv_str, sizeof(recv_str), 0)) > 0 ) {
        // Zero out the inputCopy buffer
        memset(&inputCopy, 0, sizeof(inputCopy)+1);

        // Copy the recv_str into a new string so that
        // we can work with it.
        strcpy(inputCopy, recv_str);

        argcount = parsecommand(inputCopy, args);

        //Send the message back to client
        dup2(sock_fd, 1);

        if((status = forkAndExecute(args)) != 0) {
            //printf("Command %s returned %d.\n", args[0], status);
        }

            // as a test is I uncomment the following line mkdir newdir
            // returns but the following commands are messed up - as I expect.
        //printf("\n");

        memset(&recv_str, 0, sizeof(recv_str)+1);
        fflush(stdout);
    }  

    if(rcvd_bytes == 0) {
    puts("Client disconnected");
    fflush(stdout);
    }
    else if(rcvd_bytes == -1) {
    perror("recv failed");
    exit(0);
    }

Upvotes: 1

Views: 1920

Answers (2)

JB0x2D1
JB0x2D1

Reputation: 191

Sounds like you need to use select .

if(select(fdmax+1, &my_fdset, 0, 0, NULL) > 0) // there is data available to be read
    recv(...)

where fdmax is the largest file descriptor (select wants that +1) and my_fdset is a file descriptor set that you add file descriptors to using FD_SET(sockfd, &my_fdset);.

This will only receive when there is data available. Hope that helps.

EDIT :

I asked a similar question when I was writing a simple client/server program to send/recv strings over a TCP socket. I posted the code that I ended up using on that thread here. Mine is different in that I wanted one program to send and recv but if you look at my sender or receiver functions, you may be able to adapt something to make your program do what you want.

Upvotes: 3

rra
rra

Reputation: 3887

Given your problem description, my suspicion is the client code rather than the server code -- or, actually, the protocol you've implicitly created between the two.

It looks like you're just sending the output of the command directly back to the client by using dup2 to point standard output at the socket. Presumably, the client then reads from the socket to get the output from the command? What does the client do when it sends a command to the server and then gets no reply? A command like mkdir will send nothing back. Is it waiting forever for the server to send command output?

In general, for a synchronous client/server protocol (one where the client sends a command and the server sends a response before the client sends another command), you have to agree on a protocol between the client and the server to clearly indicate when the server is done sending data back and the client should send its next command. You may need to add some way for the server to tell the client that the command completed but sent no output.

Upvotes: 1

Related Questions