Google Answers Logo
View Question
 
Q: C Programming : Client / Server Communication ( No Answer,   4 Comments )
Question  
Subject: C Programming : Client / Server Communication
Category: Computers > Programming
Asked by: ryanritten2-ga
List Price: $50.00
Posted: 16 Feb 2006 09:07 PST
Expires: 27 Feb 2006 20:04 PST
Question ID: 446564
Hello,

First of all, thankyou for taking the time to help me.  I have
honestly searched the internet and posted on many newsgroups with very
little luck on solving my problem.  I honestly believe that the
solution to my problem should be very simple and someone with some
good C experience should be able to solve it easily.

Anyways, I am creating a game that people can play over the internet. 
The user that wishes to play connects to a server that has some C code
that handles all the game data flow.  The user connects to the server
using Flash XML Sockets.... but honestly, it doesn't matter if you
know anything about that.  I've tried connecting with telnet and
another C program and they all have the same result.  So, I'm hoping
if you can help me by just telneting into the server it should work
for the Flash version as well.

Ok, now I'll explain what actually happens.  First when the user
connects to the server, the client sends in their username.  Once the
server receives their username it sends back a message to the client
saying they received their username.  Then the client sends their
password to the server.  When the server receives the password it
verifies that they logged in correctly and it sends back a message
saying they loggfed in sucessfully or not.  Then (assuming they logged
in correctly) the client sends a message saying what game they wish to
play.... and so on and so on.  You get the idea.

The point is, there is allot of back and forth communication between
the server and the client... and usually the server or the client
doesn't do anything until it receives notification that the message
was received sucessfully.

Ok, so what is the problem?  Well, if I run the server (which then
listens on a socket) and then telnet into the socket from somewhere
else on the internet (ie. not localhost) it has major delays receiving
the data.  Sometimes the data isn't received at all.  For testing
purposes with you, I wrote a very small program which gives the same
problems.

All the program below does it it waits for someone to connect, and
when they do, it sends the word "send" to them over and over once per
second. (i'll add the code at the very botton of my post)

Sometimes when I telnet into the server it writes the word "send" a
few times... sits there 5 seconds... writes a few more "sends"....
waits a 10 more seonds... writes a few more... then most of the time
it eventually just sits there and no more "sends" are printed to the
screen.

Sometimes when i connect it doesn't print anythign for a while (20
seconds) then dumps are bunch of sends to the screen (ie
"sendsendsendsendsendsendsend").

The point it, it doesn't do what it is supposed to do.  It should
print "send" once a second every second until I disconnect.  Why
doesn't this work?

I had a few thoughts that may help you.  First of all, I thought that
maybe the server was buffering the output on the socket.  I read
everywhere on the internet people claim you cannot flush a TCP socket.
 I read that if I disable the nagal algorithm this would prevent all
buffering of data.  I tried this and it didn't seem to work.  Maybe I
did it incorrectly.

I know it has nothing to do with my internet connection.  I have high
speed internet both at work and at home.  My pings are very fast...
definatley not even close to be over a second... which rules out why
packets don't seem to be arriving.

Well, I could write forever.  But I don't want to do be too long that
no one will read.....  So basically, my quetsion is :  What do i need
to do to the C code below to make everything work.  I would like to be
able to telnet into the server and have the word "send" printed once a
second every second to my screen.

If the code is perfect.... what could be causing the problem... and
how do i fix it?

Thanx for you time.  Please see the code below :

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

void error(char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portno, clilen;
     struct sockaddr_in serv_addr, cli_addr;
     int n;
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0)
        error("ERROR opening socket");
     bzero((char *) &serv_addr, sizeof(serv_addr));
     portno = 1234;
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0)
              error("ERROR on binding");
     listen(sockfd,5);
     clilen = sizeof(cli_addr);
     newsockfd = accept(sockfd,
                 (struct sockaddr *) &cli_addr,
                 &clilen);
     while(1)
     {
        write(newsockfd,"send",4);
        sleep(1);
     }
     return 0;
}
Answer  
There is no answer at this time.

Comments  
Subject: Re: C Programming : Client / Server Communication
From: krishpi-ga on 17 Feb 2006 11:03 PST
 
Just replace

write(newsockfd,"send",4);

by

send(newsockfd,"send",4, 0);

and it will work

Hope this helps
Krish
Subject: Re: C Programming : Client / Server Communication
From: rssohan-ga on 17 Feb 2006 15:56 PST
 
Hi,

I took a quick look/test of your code.  It seems fine to me.  I don't
think the above code will help you -- you don't say what your OS is,
I'll assume Linux as this is POSIX code.  The send() and write()
functions map to an identical kernel function in linux (with minor
setup differences).

I tried running this on 2 machines and connecting from various places
(total of 5 connections in total).  In all instances it worked fine. 
The symptoms you describe seem very much like congestion.  In short,
it's difficult to debug the situation without looking at your test
environment but your code seems fine; I think (I may be wrong) it's a
function of the network.  Try pinging your server from your client and
seeing whether you loose packets; remember, as long as you have
congestion between client and server at ANY point in the link you will
experience problems, so great connectivity in general doesn't say
much.

BTW, to turn off NAGLES on Linux the correct code block is:

 {
        int opt=1;
        int ret;
        ret=setsockopt(sockfd,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(opt));
        if (ret==-1)
          error("problem setting TCP_NODELAY");
}
Subject: Re: C Programming : Client / Server Communication
From: ryanritten2-ga on 17 Feb 2006 16:40 PST
 
Thanks for taking the time to try and help me.  I have tried both
write and send and (just like rssohan said) they both do the same
thing.

Mu OS is in fact linux.  When you said you connected from 5 places...
where all those places from within the same network?  or were they
across the internet?  I know when I connect from a computer on the
same network.. there is no problem.

If I try and ping my server from somewhere across the internet, the
ping always times out because I have a router.  I'm not much of a
network guru but i assume that the router drops ping packets.

Oddly enough when I added the code to remove nagal's algorithm, I got this error.  

[postgres@localhost postgres]$ gcc -lpthread -lpq -o server test.c
test.c: In function `main':
test.c:24: `TCP_NODELAY' undeclared (first use in this function)
test.c:24: (Each undeclared identifier is reported only once
test.c:24: for each function it appears in.)
[postgres@localhost postgres]$

I'll go read a bit up on it... I'm sure I messed somethign up :)

thanx again
Subject: Re: C Programming : Client / Server Communication
From: rssohan-ga on 17 Feb 2006 17:19 PST
 
Hi,

1. I tried from 5 connections on computers in different networks, but
all of the machines were in the UK (ping time <= 50ms).  All machines
were on well-provisioned networks (2MB+) and considering it was done
at approx. 11pm, I assume traffic was low.

2. If your router is dropping ping packets, you could try temporarily
allowing ICMP packets through just to give you an idea of the ping
times.  Another option might be to ping your source from within your
home network (the wrong way round).

3. Sorry, I forgot to tell you.. at the start include netinet/tcp.h
(#include <netinet/tcp.h>)

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy