0

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");
}
1
  • You might want to add some code to check that the reads and writes actually succeeded Commented May 30, 2015 at 9:47

4 Answers 4

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

this worked for not printing twice but now its closing the connection on random character.
use this while((n = read(sockfd, &ch, 1))>0) instead of while(1) @AliRehman
where exactly do i have to use it?
0

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.

3 Comments

Thanks alot. Its working fine now. I have also edited the while loop in client side while(m>0) where m has the return value of client side read. It isnt doing anything out of ordinary but do tell me if its okay to do so. @Subinoy
Always use the return values of functions. It's good for program. :-)
The while in client side will wait until the server response and till then you can't give inputs @AliRehman
0
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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.