|
Home > Archive > Unix Programming > March 2005 > select and sockets problem
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
select and sockets problem
|
|
| Ulrich Hobelmann 2005-03-27, 8:47 pm |
| Hi, I'm writing the most minimally useful sockets example, a
server and and a client.
The server accept one connection, services it like the client,
until the socket is closed.
Both client and server work by select()ing on 0 (stdin) and s (the
connection socket). They then read stuff from the active stream
into a buffer and out to stdout or the socket respectively.
So in effect this is a simple chat tool, with the server having
its own console too.
For some reason though the data doesn't get sent or isn't received
correctly. Both client and server are stuck in select() until I
type something in and hit enter. Now this data is read() and
write()en out to the socket. On the other side, however, select
doesn't wake up. Both sides are symmetric in this.
Here's code from the client:
static void connect(const char * server, int port)
{
int n;
fd_set streams;
// this connects and returns the fd
int s = newSocket(server, port);
FD_ZERO(&streams);
for (;;) {
FD_SET(0, &streams);
FD_SET(s, &streams);
n = select(2, &streams, 0, 0, 0);
if (n == -1) error("select: %s", strerror(errno));
// if stdin is set xfer from stdin to s
if (FD_ISSET(0, &streams) && xfer(0, s)) {
// if EOF in stdin
close(s);
return;
}
// if s is set xfer from s to stdout
if (FD_ISSET(s, &streams) && xfer(s, 1)) {
// if EOF in s
close(s);
return;
}
}
}
/* returns: EOF? */
static int xfer(int in, int out)
{
int n; char buf[128];
n = read(in, buf, 128);
if (n == -1) error("read: %s", strerror(errno));
if (n == 0) return 1;
write(out, buf, n);
return 0;
}
Am I doing anything wrong with the fd_sets?
Here's the server's main function:
static void listen(int port)
{
int n, s;
fd_set streams;
// creates listening socket
int sock = newServerSocket(port);
for (;;) {
// accepts and returns connection
s = serverSocketAccept(sock);
FD_ZERO(&streams);
for (;;) {
FD_SET(0, &streams);
FD_SET(s, &streams);
n = select(2, &streams, 0, 0, 0);
if (n == -1) error("select: %s", strerror(errno));
if (FD_ISSET(0, &streams) && xfer(0, s)) {
close(s);
close(sock);
return;
}
if (FD_ISSET(s, &streams) && xfer(s, 1)) {
close(s);
break;
}
}
}
}
| |
| Malte Starostik 2005-03-27, 8:47 pm |
| Ulrich Hobelmann schrieb:
> Hi, I'm writing the most minimally useful sockets example, a server and
> and a client.
> The server accept one connection, services it like the client, until the
> socket is closed.
>
> For some reason though the data doesn't get sent or isn't received
> correctly. Both client and server are stuck in select() until I type
> something in and hit enter. Now this data is read() and write()en out
> to the socket. On the other side, however, select doesn't wake up.
> Both sides are symmetric in this.
>
> FD_SET(0, &streams);
> FD_SET(s, &streams);
> n = select(2, &streams, 0, 0, 0);
The second argument to select() is often called nfds, which is a bit of
a misnomer as it might look like you need to pass the number of
filedescriptors. In fact, what you need to pass there is the maximum fd
included in any of the sets + 1, in your simple case s + 1.
HTH,
Malte
| |
| Malte Starostik 2005-03-27, 8:47 pm |
| Malte Starostik schrieb:
> The second argument to select() is often called nfds
^^^^^^ make that first *sigh*
Cheers,
Malte
| |
| Ulrich Hobelmann 2005-03-27, 8:47 pm |
| Malte Starostik wrote:
>
>
> The second argument to select() is often called nfds, which is a bit of
> a misnomer as it might look like you need to pass the number of
> filedescriptors. In fact, what you need to pass there is the maximum fd
> included in any of the sets + 1, in your simple case s + 1.
Thanks for the instant response! This has to be the classic
select() error. My manpage says: "The first nfds descriptors are
checked in each set; i.e., the descriptors from 0 through nfds-1
in the descriptor sets are examined."
I only read "the first nfds descriptors are checked" and thought
that refers to MY two descriptors 
I guess select is very wasteful when I give it fd 0 and fd 200 :D
I even remember having made the same mistake a couple years back
(actually finding it on my own), but I don't seem to have the code
around.
(It works now)
| |
|
| Ulrich Hobelmann wrote:
>
>
> I guess select is very wasteful when I give it fd 0 and fd 200 :D
>
Don't worry. You would notice.
> I even remember having made the same mistake a couple years back
> (actually finding it on my own), but I don't seem to have the code around.
>
> (It works now)
Good.
Just one detail: one of your static functions is called connect();
That will (at least) confuse human readers.
AvK
| |
| Ulrich Hobelmann 2005-03-29, 2:49 am |
| moi wrote:
> Good.
> Just one detail: one of your static functions is called connect();
> That will (at least) confuse human readers.
I know. A put all socket stuff behind abstractions, because the
socket API is really ugly IMHO 
The static function is called connect (like the program), because
I couldn't find a better name for it.
|
|
|
|
|