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

NO second FD_WRITE NetworkEvent on UDP socket whith SP5

84 views
Skip to first unread message

Richard Wirth

unread,
Aug 24, 1999, 3:00:00 AM8/24/99
to
On an UDP socket only the first WSAEventSelect() with FD_WRITE set
leads to an Event in WSAEnumNetworkEvents().
All subseqent calls to WSAEventSelect( "FD_WRITE") do not produce a
NetworkEvent.
It looks like the UDP-Socket never gets ready for writing again after
a call to sendto();
The identical code (even the binary) was working well on SP3 and fails
on SP5.
Did they change anything? Or did I something wrong?

Best regards

Richard

Andy Lutomirski

unread,
Aug 24, 1999, 3:00:00 AM8/24/99
to
Post a code snippet. Maybe you have a funny race condition or you forgot to reset the event or something.

Andy

Richard Wirth <r.w...@wirthware.da-net.de> wrote in message news:37c31b3a...@news.btx.dtag.de...

Richard Wirth

unread,
Aug 25, 1999, 3:00:00 AM8/25/99
to
On Tue, 24 Aug 1999 18:01:08 -0700, "Andy Lutomirski"
<lu...@mailandnews.nospam.com> wrote:

>Post a code snippet. Maybe you have a funny race condition or you =


>forgot to reset the event or something.
>
>Andy
>

>Richard Wirth <r.w...@wirthware.da-net.de> wrote in message =


>news:37c31b3a...@news.btx.dtag.de...
>> On an UDP socket only the first WSAEventSelect() with FD_WRITE set
>> leads to an Event in WSAEnumNetworkEvents().
>> All subseqent calls to WSAEventSelect( "FD_WRITE") do not produce a
>> NetworkEvent.
>> It looks like the UDP-Socket never gets ready for writing again after
>> a call to sendto();
>> The identical code (even the binary) was working well on SP3 and fails
>> on SP5.
>> Did they change anything? Or did I something wrong?

>>=20
>> Best regards
>>=20
>> Richard
>
>

Here is a code snippet. It's from a library which also works on unix
platforms and on VxWorks. So many sentences of the original code
are removed and some lines are pseudo code.
(The called functions are appended at the end.)

/* Initialize WINDOWS network ... */
if ((status = WSAStartup(MAKEWORD(2,0), &WSAData)) != 0) {
....
exit (-1);
}

...

SocketList.Add( CreateUdpSocket( 8998));

...

while (1)
{
// First setup all event masks for all active sockets
for( iterator = SocketList.begin();...)
{
DWORD evm = FD_ACCEPT | FD_CONNECT | FD_CLOSE
| ((iterator->MUX_POLLIN)? FD_READ : 0) | ((iterator->MUX_POLLOUT)?
FD_WRITE : 0);
if( WSAEventSelect( iterator->fd, evt_arr[1],
evm))
{
printf( "_server: EventSelect failed
(%d)\n", WSAGetLastError());
return -1;
}
}
.....


// Wait for something
DWORD to;
DWORD rx;
to = Calculate_TimeOut();
rx = WSAWaitForMultipleEvents( NUM_EVTS, evt_arr,
FALSE, to, FALSE);
switch( rx)
{
case WSA_WAIT_EVENT_0+1: // socket transfer
r=1;
break;
case WSA_WAIT_EVENT_0: // pipe event
pipe_hndl();
case WSA_WAIT_TIMEOUT:
r=0;
break;
case WSA_WAIT_FAILED:
default:
r=-1;
}

....

if (r == -1) {
r = WSAGetLastError();
printf ("select failed with error: %d\n", r);

/* poll or select failed -- bad news */
if (__debug > 13) {
printf ("ERROR: _DoServe(): select()
failed\n");
}
return -1;
}

....

if( r == 0)
continue; // restart the outer loop

// socket event ... search the list
for( iterator = SocketList.begin();...)
{
WSANETWORKEVENTS sevt;
ZeroMemory( &sevt, sizeof( sevt));
if( WSAEnumNetworkEvents( iterator->fd, 0,
&sevt))
printf( "_server: EnumEvents failed
%d\n", WSAGetLastError());
else
ev = ((sevt.lNetworkEvents & (FD_READ
| FD_ACCEPT | FD_CONNECT | FD_CLOSE))?MUX_POLLIN:0)
| ((sevt.lNetworkEvents &
FD_WRITE)?MUX_POLLOUT:0);

.....

if (ev) {
/* Normal event, do callout */
(*iterator->pfvHandle) (iterator, ev);
// for udp sockets this calls "udpio_handle()" ( see below)
}
}

} // end while( 1)


////////////////////////////////////////////////////////////////////////////
// here are the elsewhere called functions:


void udpio_handle (struct mux_fd *pMuxFd, int events) {

....

if (events & MUX_POLLOUT) {

....

r = sendto( pMuxFd->fd,
pcData, iSize, 0,
(struct sockaddr *)&saddr, sizeof
(saddr));
}
}

if (events & MUX_POLLIN) {
...
}
}


// create a new UDP Socket

int CreateUdpSocket (int iPort) {
struct sockaddr_in saddr;

int r, len;

int iSock;

iSock = WSASocket (AF_INET, SOCK_DGRAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED);

if (iSock == -1) {
return -1;
}

saddr.sin_family = AF_INET;
saddr.sin_port = htons ((unsigned short)iPort);
/* Incompatible change, strictly speaking... AK 15Oct96 */
saddr.sin_addr.s_addr = INADDR_ANY;

saddr.sin_zero [0] = 0;
saddr.sin_zero [1] = 0;
saddr.sin_zero [2] = 0;
saddr.sin_zero [3] = 0;
saddr.sin_zero [4] = 0;
saddr.sin_zero [5] = 0;
saddr.sin_zero [6] = 0;
saddr.sin_zero [7] = 0;

r = bind (iSock, (void*)&saddr, sizeof (saddr));
if (r == -1) {
MUX_closesocket (iSock);
return -2;
}

len = sizeof (saddr);
r = getsockname (iSock, (void*)&saddr, &len);

if (iDebugLevel > 4) {
printf ("CreateUdpSocket: Addr=%x, port=%d\n",
(unsigned)ntohl (saddr.sin_addr.s_addr),
(int)ntohs (saddr.sin_port));
}

return iSock;
}


Andy Lutomirski

unread,
Aug 25, 1999, 3:00:00 AM8/25/99
to
I would first try setting winsock 2.2 not 2.0. I have best luck that way.

Then, try manual-reset event, and pass TRUE to WSAEnumNetworkEvents.

Andy

Gary Nebbett

unread,
Aug 25, 1999, 3:00:00 AM8/25/99
to
Richard Wirth <r.w...@wirthware.da-net.de> wrote in message
news:37c31b3a...@news.btx.dtag.de...
> On an UDP socket only the first WSAEventSelect() with FD_WRITE set
> leads to an Event in WSAEnumNetworkEvents().
> All subseqent calls to WSAEventSelect( "FD_WRITE") do not produce a
> NetworkEvent.
> It looks like the UDP-Socket never gets ready for writing again after
> a call to sendto();
> The identical code (even the binary) was working well on SP3 and fails
> on SP5.
> Did they change anything? Or did I something wrong?

It may be the case that something changed, but the current behaviour matches the documentation. Here
is the relevant extract:
The FD_WRITE network event is handled slightly differently. An FD_WRITE network event is recorded
when a socket is first connected with WSPConnect or accepted with WSPAccept, and then after a
WSPSend or WSPSendTo fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, a
Windows Sockets SPI client can assume that sends are possible starting from the first FD_WRITE
network event setting and lasting until a send returns WSAEWOULDBLOCK. After such a failure the
Windows Sockets SPI client will find out that sends are again possible when an FD_WRITE network
event is recorded and the associated event object is signaled.

Since UDP does not provide any flow control, it is unlikely that a send would ever fail with
WSAEWOULDBLOCK.

Gary


Richard Wirth

unread,
Aug 25, 1999, 3:00:00 AM8/25/99
to

As you say "sendto() on an udp socket will never fail with
WSAEWOULDBLOCK. Thus I think, I never will get a FD_WRITE event on an
udp socket again after connect ( only if the target is konnected via
serial line or so)?
But why is the binary working on SP3? Is this an unknown bug in SP3?

But thanks to all!
I think this way, the code is working well now.

Best regards

Richard


0 new messages