Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

select() monitoring multiple sockets

134 views
Skip to first unread message

Chad Dixon

unread,
Oct 21, 1999, 3:00:00 AM10/21/99
to
Hi,

I have tried to get this one on my own and cant come up with
the answer. Basically what I am doing is this .. I create 2 sockets
one tcp , one udp , and bind both , then use select() to listen for
incoming connections ..

The problem: If the first packet to come in is a tcp based connection,
the server will happily accept it and continue accepting tcp based
connections. It will never see the udp socket as having data ready.
But, if the udp socket gets the first packet, it will continue accepting
udp based data, and select will never get a flag on the tcp socket.

Both work independantly .. the sockets are not hanging on recv()
recvfrom().. it simple goes back to select() and waits there for the next
packet using the connection type that its first connection was ..

example -- (just trying to make the issue clear)

lets say I send the following data to the server in the followgin modes :
client being executable | mode of transport | server hostname | string to
send|
client tcp server foo
client udp server hello
client tcp server bar
client tcp server baz
client udp server grrrr

#server &
*connection from TCP, recv'd "foo"
*connection from TCP, recv'd "bar"
*connection from TCP, recv'd "baz"

..

and the opposite would be true if the first data recvd was UDP .. it would
be only accept as such.


The source code is available at :
http://216.202.79.15/problem/unix.c.txt
I even ported it thinking I was seeing a potential quirk .. windows source
is at :
http://216.202.79.15/problem/windows.c.txt
But as both do the same thing , it's pretty obvious it's my code ..
Thanks in advance,
Chad Dixon

Barry Margolin

unread,
Oct 21, 1999, 3:00:00 AM10/21/99
to
In article <s0tq6k...@corp.supernews.com>,

Chad Dixon <127...@iwl.net> wrote:
>The problem: If the first packet to come in is a tcp based connection,
>the server will happily accept it and continue accepting tcp based
>connections. It will never see the udp socket as having data ready.
>But, if the udp socket gets the first packet, it will continue accepting
>udp based data, and select will never get a flag on the tcp socket.

You're not calling FD_SET() in your loop. Remember, select() modifies the
fd_set, so that only the bits for the descriptors that succeeded are set.
You need to call FD_SET() again on the other bits, so that the next call to
select() will check those descriptors as well. Your code should look like:

while(1)
{
FD_SET(sockfd_tcp, &readset);
FD_SET(sockfd_udp, &readset);
if (select (max+1, &readset, NULL, NULL, &tv) > 0)

See the note near the top of p.153, and Figure 6.9 on p.157, of "Unix
Network Programming, 2nd Edition, Vol.1". If you don't have this book, can
you really call yourself a network programmer?

--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Alun Jones

unread,
Oct 21, 1999, 3:00:00 AM10/21/99
to
In article <s0tq6k...@corp.supernews.com>, "Chad Dixon" <127...@iwl.net>
wrote:
> I have tried to get this one on my own and cant come up with
> the answer. Basically what I am doing is this .. I create 2 sockets
> one tcp , one udp , and bind both , then use select() to listen for
> incoming connections ..
...

> I even ported it thinking I was seeing a potential quirk .. windows source
> is at :
> http://216.202.79.15/problem/windows.c.txt
> But as both do the same thing , it's pretty obvious it's my code ..

Please note, on the Windows front, because multiple Layered Service
Providers are supported, it is actually _illegal_ for you to call select
with a mixed FD_SET such as this. select() should signal WSAENOTSOCK from
the first time you call [but it doesn't because Microsoft's rpc software
uses this feature - for now, it's been promised to be fixed].

Alun.
~~~~

--
Texas Imperial Software | Try WFTPD, the Windows FTP Server. Find it
1602 Harvest Moon Place | at web site http://www.wftpd.com or email
Cedar Park TX 78613 | us at al...@texis.com. VISA / MC accepted.
Fax +1 (512) 378 3246 | NT based ISPs, be sure to read details of
Phone +1 (512) 378 3246 | WFTPD Pro, NT service version - $100.
*WFTPD and WFTPD Pro now available as native Alpha versions for NT*

Dan Lanciani

unread,
Oct 21, 1999, 3:00:00 AM10/21/99
to
In article <7uneem$hg0o...@news.io.com>, al...@texis.com (Alun Jones) writes:

| Please note, on the Windows front, because multiple Layered Service
| Providers are supported, it is actually _illegal_ for you to call select
| with a mixed FD_SET such as this.

I hate to belabor this point, but the reason that it is illegal to call
select with a mixed set of descriptors is not that multiple layered
service providers are supported. The reason is that Microsoft's service
provider interface is poorly designed. The SPI could have been designed
to support standard socket semantics on select, but it would have required
a slight reach: the SPI primitive to implement select() would not look
like select() and the API "router" would have had a little more code in
it (not that it is by any means transparent as it stands).

Dan Lanciani
ddl@danlan.*com

John Maline

unread,
Oct 21, 1999, 3:00:00 AM10/21/99
to
...discussion of calling select w/ TCP and UDP socket handles...

Alun says:

> Please note, on the Windows front, because multiple Layered Service
> Providers are supported, it is actually _illegal_ for you to call select

> with a mixed FD_SET such as this. select() should signal WSAENOTSOCK from
> the first time you call [but it doesn't because Microsoft's rpc software
> uses this feature - for now, it's been promised to be fixed].

Surely you must be kidding! I'm amazed.

I support a communication layer that uses a mix of TCP for communication and UDP
for internal coordination w/ a central admin process. Of course I select() on a
UDP socket and one or more TCP sockets.

I don't think this mix of TCP & UDP is an uncommon pattern. For example,
Inprise's CORBA software uses a similar architecture. MS uses it in their RPC
stuff, apparently.

So now I can count on this breaking at some time in the future. No doubt when I
upgrade the dancing paperclip software and it silently upgrades my winsock and
installs IE6 to boot. OK, I'll try to get back to the subject. (sound of deep
breath being taken)

Do you have a pointer to docs describing this? Any sensible workarounds?

I've checked the winsock2 spec and see the info on select's readfds needing to be
from one service provider. I didn't chase it down far enough to know that TCP
and UDP would have different service provider id. Not knowing that end at all,
I'll have to take your word for it.

John

--
John Maline jma...@ti.com
Texas Instruments PO Box 655303 MS 3660 Dallas, TX 75265 972-927-5615

Alun Jones

unread,
Oct 22, 1999, 3:00:00 AM10/22/99
to
In article <538...@news1.IPSWITCHS.CMM>, ddl@danlan.*com (Dan Lanciani)
wrote:

> In article <7uneem$hg0o...@news.io.com>, al...@texis.com (Alun Jones) writes:
>
> | Please note, on the Windows front, because multiple Layered Service
> | Providers are supported, it is actually _illegal_ for you to call select
> | with a mixed FD_SET such as this.
>
> I hate to belabor this point, but the reason that it is illegal to call
> select with a mixed set of descriptors is not that multiple layered
> service providers are supported. The reason is that Microsoft's service
> provider interface is poorly designed. The SPI could have been designed
> to support standard socket semantics on select, but it would have required
> a slight reach: the SPI primitive to implement select() would not look
> like select() and the API "router" would have had a little more code in
> it (not that it is by any means transparent as it stands).

To be honest, I'm partly of the opinion that it could have been done without
any problems by having the select() function in the API->SPI conversion kick
off multiple waits on select()s to the lower stacks. But since I don't
currently write at that kind of level, I'm not about to say I could do it
better.

Alun Jones

unread,
Oct 22, 1999, 3:00:00 AM10/22/99
to
In article <380F7D5A...@ti.com>, John Maline <jma...@ti.com> wrote:
> ....discussion of calling select w/ TCP and UDP socket handles...

>
> Alun says:
>
> > Please note, on the Windows front, because multiple Layered Service
> > Providers are supported, it is actually _illegal_ for you to call select
> > with a mixed FD_SET such as this. select() should signal WSAENOTSOCK from
> > the first time you call [but it doesn't because Microsoft's rpc software
> > uses this feature - for now, it's been promised to be fixed].
>
> Surely you must be kidding! I'm amazed.

No - I'm totally serious, and this has already bitten a number of people. A
number of LSPs have been written and tested, and the authors found their
systems hanging at boot time because the services called RPC, which mixes
TCP and UDP.

> I support a communication layer that uses a mix of TCP for communication and
> UDP
> for internal coordination w/ a central admin process. Of course I select() on
> a
> UDP socket and one or more TCP sockets.
>
> I don't think this mix of TCP & UDP is an uncommon pattern. For example,
> Inprise's CORBA software uses a similar architecture. MS uses it in their RPC
> stuff, apparently.
>
> So now I can count on this breaking at some time in the future. No doubt when
> I
> upgrade the dancing paperclip software and it silently upgrades my winsock and
> installs IE6 to boot. OK, I'll try to get back to the subject. (sound of
> deep
> breath being taken)

To be honest, it'll probably happen when someone _other_ than Microsoft
installs, say, a TCP LSP without also implementing UDP. Microsoft additions
are likely to install both services through the one provider.

> Do you have a pointer to docs describing this? Any sensible workarounds?
>
> I've checked the winsock2 spec and see the info on select's readfds needing to
> be
> from one service provider. I didn't chase it down far enough to know that TCP
> and UDP would have different service provider id. Not knowing that end at
> all,
> I'll have to take your word for it.

I couldn't find any specific documentation in a quick search that would say
exactly what you're looking for, but yes, it's dependent on whether someone
installed a TCP service provider and didn't simultaneously add on a UDP
service provider.

You'll get ENOTSOCK, incidentally, as the response code, which may allow you
to make a decision as to how to handle this - perhaps separate threads, or
using one of the WSA*Select functions.

Dan Lanciani

unread,
Oct 22, 1999, 3:00:00 AM10/22/99
to
In article <7uoeig$ak0n...@news.io.com>, al...@texis.com (Alun Jones) writes:
| In article <538...@news1.IPSWITCHS.CMM>, ddl@danlan.*com (Dan Lanciani)
| wrote:
| > In article <7uneem$hg0o...@news.io.com>, al...@texis.com (Alun Jones) writes:
| >
| > | Please note, on the Windows front, because multiple Layered Service
| > | Providers are supported, it is actually _illegal_ for you to call select
| > | with a mixed FD_SET such as this.
| >
| > I hate to belabor this point, but the reason that it is illegal to call
| > select with a mixed set of descriptors is not that multiple layered
| > service providers are supported. The reason is that Microsoft's service
| > provider interface is poorly designed. The SPI could have been designed
| > to support standard socket semantics on select, but it would have required
| > a slight reach: the SPI primitive to implement select() would not look
| > like select() and the API "router" would have had a little more code in
| > it (not that it is by any means transparent as it stands).
|
| To be honest, I'm partly of the opinion that it could have been done without
| any problems by having the select() function in the API->SPI conversion kick
| off multiple waits on select()s to the lower stacks.

I was going to add that I thought it might yet be possible to correctly
implement select() as you suggest in the API router without changing the
SPI. But then I realized that there might well be a resource consumption
issue with the synchronization objects. In any case, a reasonably designed
SPI would obviate the need to even consider such kludges...

| But since I don't
| currently write at that kind of level, I'm not about to say I could do it
| better.

Well, I'll say that I could do it better. I did it long ago on OS/2. My
SPI (which of course I didn't call an SPI) provided a mechanism for registering
objects to be awakened in support of the select() function in the API. The
select() function supported not only tcp and udp sockets through the ip stacks's
SPI but even console keyboard input!

Dan Lanciani
ddl@danlan.*com

0 new messages