Hello,

I'm trying to make client program which connects to server, and comunicates with it for unlimited time. SOCK_STREAM (TCP).

Is there a way to change the way of getting server messages? Now it's just infinite loop. (I think thats not good, and requires a lot of CPU cycles)

while (1) {
    memset(buff,0,255);
    recv( sock,buff,255,0);

    if (strstr(buff,"PING") != 0)
        send(sock,"PONG :\r\n",6,0);

    if (strlen(buff) == 0) 
    {
        closesocket(sock);
        break;
    }
    memset(buff,0,255);
}

As you see - very not good :( So is there a way to change 'while' into some kind of 'when'. So the client program would sleep until it get's messages?

Something like:

when (you_got_message() == true)
{
   function that responses to server
}

Doe's this make any sence? :)

Pls help me and the world :D

Recommended Answers

All 7 Replies

> recv( sock,buff,255,0);
1. You ignore the return result.
2. Despite all your memsetting, you still have the potential for a buffer overflow. If the recv() happens to FILL your buffer, there is no \0 at the end of it to mark the end of the string.
3. TCP is a stream protocol, so the minimum guaranteed number of bytes in a successful recv() call is 1.

The server might send "PING\r\n", but you might only recv() "PIN" on the first call, then "G\r\n" on the second call. This message reassembly is YOUR job to do.

It's a good idea to separate the "get a message" from the "process a message".

> So is there a way to change 'while' into some kind of 'when'.
Yes, look up the select call.
You can use this to wait for all sorts of sockets to become ready.
You can even supply a timeout in case you get bored of waiting, and need to go and do something else for a while.

http://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-2.html

2.9 What are the pros/cons of select(), non-blocking I/O and SIGIO?

Using non-blocking I/O means that you have to poll sockets to see if there is data to be read from them. Polling should usually be avoided since it uses more CPU time than other techniques.

Using SIGIO allows your application to do what it does and have the operating system tell it (with a signal) that there is data waiting for it on a socket. The only drawback to this soltion is that it can be confusing, and if you are dealing with multiple sockets you will have to do a select() anyway to find out which one(s) is ready to be read.

Using select() is great if your application has to accept data from more than one socket at a time since it will block until any one of a number of sockets is ready with data. One other advantage to select() is that you can set a time-out value after which control will be returned to you whether any of the sockets have data for you or not.

Em... Is select() call so expensive? I mean - more than 1000... cycles of while every second? Or there is something i don't understand :/ ?

Where did you get 1000 from?
Or indeed the idea that select() might be expensive, from the link you posted.

In principle, the process should be asleep in a select call until the OS wakes it up with something to do.

It's gotta be better than a bunch of poll() calls, or heaven forbid a while(1) loop.

Eample code would be very helpfull, becouse from all example codes with select(), i still have to use while(1) or for(;;) loop. So what's the point of select()? How should i make my program go asleep and wake up when OS tells that i have something to read?

> How should i make my program go asleep and wake up when OS tells that i have something to read?
You just described select()

You don't need to do anything to make your process go to sleep, or to get it to wake up later on.

while ( (status=select(....)) >= 0 ) {
  if ( status == 0 ) {
    // timeout
  } else {
    // one or more file descriptors are ready, do something
  }
}

last question :) this client is not ordinary client it is "client side server"
e.g irc server - would be server, irc bot - would be client side server. ;)

So, this "client side sever" must anwser/reponse immediately.

while ( (status=select(....)) >= 0 ) {
  if ( status == 0 ) {
    // timeout
  } else {
    // one or more file descriptors are ready, do something
  }
}

if i set timeout for e.g 5 seconds - while loop will be runed again after 5 secconds? i'm rigth? or the while loop will go again as fast as CPU 'n' krnl let's, to check if there's file descriptor ready for reading?

if not, i gues program will fall 'asleep' until OS tells to wake up and do smth? i'm rigth this time? :D

Sorry i'm new to socket stuff in c :)

> if i set timeout for e.g 5 seconds - while loop will be runed again after 5 secconds?
It will run
- when there is data to be read, or
- there is a timeout

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.