Ali Rehman
Ali Rehman

Reputation: 43

socket programming in c unix

I have written a server/client based c program. The basic function of the program is that client will send a character e.g to server, The server will increment it and send the character back. So if a client sends 'a' it will receive 'b'. But when the client sends a 'q' the server is supposed to close the connection. The program is doing what its supposed to do but on client side its printing "Enter a character" and "Character from server" twice. Also sending a 'q' does close the connection but only if you send it for the second time.

Here is the server side code

void *client_thread(void *client_sockfd){
    int socket=*(int *)client_sockfd;
    while(1){
        read(socket, &ch, 1);
        if(ch=='q')
        {
            close(socket); 
        }
        else 
        {
            ch++;
            write(socket, &ch, 1);
        }
    }
    //close(socket);
    printf("Connection closed with %d",socket);       

}//end fucntion

client side code

while(1)
{
    printf("Enter a character");
    scanf("%c",&ch);  
    write(sockfd, &ch, 1);
    read(sockfd, &ch, 1);
    printf("char from server = %c\n", ch);

    //  close(sockfd);
    //exit(0);
}
if(ch=='q'){
    printf("Server closed the connection");
}

Upvotes: 0

Views: 511

Answers (4)

Subinoy
Subinoy

Reputation: 488

Client Side: Here the two lines are printed because there are two inputs one is your character and second is enter or \n

So use scanf("%c%c",&ch); in the client side.

Server Side: And second use while((n = read(sockfd, &ch, 1))>0) to stop it from terminating the connection automatically. The read statement returns the number of bytes read.

Because the value you provide is not erased after getting increment. The reason is:

  • Suppose your input is a, then the server responses b to you and as you are not checking the return value of read in the server side, so it increments ch every time and as it reaches q and the socket gets closed.
  • When the server increments the value it also sends it to client but as the client is in scanf mode it can't get the input until the read statement, for this reason you can't see the automated increment value. And the increment is so fast that before your next input the socket already have been terminated.

Upvotes: 0

Les
Les

Reputation: 10595

Your program is doing the following...

  1. Prints the message, "Enter a character" and blocks waiting for STDIN
  2. User types 'a' and '\n' - scanf() does not return control until a newline
  3. Writes 'a', reads 'b', prints 'b' and then prompts "Enter a character"
  4. Scanf has a character already (\n) so it returns immediately
  5. Writes '\n', reads '\n'+1, prints '\n'+1 and prompts "Enter a character"
  6. Repeats from 1.

This is why you see "Enter a character" twice.

As for having to send 'q' twice, your server loop does not exit when it receives the 'q', it calls close and continues reading. Each read after that will fail and return immediately with an error code. Similarly, your client loop doesn't break out.

Capture and test your return values. Also, step through with a debugger - this will answer many of your questions about C without having to wait for the forums to respond.

Upvotes: 0

wholerabbit
wholerabbit

Reputation: 11536

printf("Enter a character");
scanf("%c",&ch); 

You actually enter two characters here, one for each key you press, the second of which is from Enter, and that is a newline, /n. This is why every other output from

printf("char from server = %c\n", ch);

Is probably:

char from server =

Then there's a blank line, then another output. If you did this instead:

printf("char from server = %d\n", (int)ch);
                       //   ^ not %c

The cast to int is not really necessary there but stresses the idea; you'll now get the decimal ASCII value of the character, and every other line will now be:

char from server = 10

That's the newline. For a way to deal with this issue, which has caught up countless C neophytes before you, see my answer here.

Upvotes: 0

fede1024
fede1024

Reputation: 3098

The scanf is reading one character at a time, so when you type a character and press enter, the first cycle will read the character, the second one will read the newline.

You can use

scanf("%c%*c", &ch);

that reads the two characters, but stores only the first one.

Upvotes: 1

Related Questions