Reputation: 10005
i try to do a kind-of chat over TCP sockets. The server side is implemented in php and (should) work fine.
No i've encountered a problem on the client side (implemented in c [c99]):
i'd like to listen (read) for "new bytes" from the server and i also would like to send (write) "some bytes" to the server whenever the user did enter new data.
Now the question: -> how do i listen for incoming traffic (read) and still be able to call every 1 seconds a callback where i can check for new bytes to send to the server? I know that i have to use select (system call) but i do not have a idea how to handle the timeout etc. select is also blocking for a certain time.
Thanks for any example.
Upvotes: 1
Views: 2179
Reputation: 409166
There is a function called select
that can be used for this. It can check if there is new input on a socket to read, and it has a timeout so it can be used for your timer as well.
It exists on one form or other on all major operating systems. Just do a Google search for socket select <your operating system> example
and you will get a boat-load of results.
The last argument to select
is used for the timeout. It's a pointer to a struct timeval
, a structure which contains fields to set the timeout.
If this pointer is passed as NULL
then there is no timeout, and select
can block indefinitely.
To set a timeout, you need to set the tv_sec
field of the timeval
structure to the number of seconds, and the tv_usec
field to the number of microseconds (must be less than one million). You can have a timeout of zero, i.e. just a quick poll, by setting these fields to zero.
If select
returns zero, then there was a timeout.
Example, with a 1.5 second timeout:
for (;;)
{
fd_set readset;
int maxfd;
/* Initialize and set `readset` and `maxfd` */
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 500000;
int res = select(maxfd + 1, &readset, NULL, NULL, &tv);
if (res == -1)
perror("select"); /* Error */
else if (res == 0)
{
/* Timeout, do something */
}
else
{
/* A socket in `readset` is readable */
}
}
If select
returns before the timeout, the timeval
structure is modified to contain the time remaining of the timeout.
Upvotes: 1
Reputation: 22318
Use the select system call, with the timeout
parameter set as needed.
Beej's guide is still a good source with plenty of example code.
Upvotes: 0