OhGod

I'm writing an application that I want to listen on a UDP socket and to wake up every time a message is received so it can process it, and to also wake up after if a certain time out has expired so it can do some book keeping and various other tasks, and then loop round again.

Below is quick sample to show the problem. From what I've always understood of Select, and what the documentation says, it should sleep for up to the time out (5s here) waiting for data, but it doesn't. It just returns immediately whether there's data or not - though the collection is empty when there's no data so that part of it is correct. The end result is this is a constant loop, CPU usage goes to 100% and is just generally bad. I could put in a Sleep, but that wouldn't be able to wake up when a packet is received. I could make use of threads, or asynchronous calls, but it all seems to be a completed work around for something that should just work.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim m_Socket As Socket
Dim BindAddr As IPEndPoint
Dim FromAddr As IPEndPoint

Dim Sockets As New Collection

Dim Buffer(512) As Byte

m_Socket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)

BindAddr = New IPEndPoint(IPAddress.Parse("192.168.130.67"), 5000)
m_Socket.Bind(BindAddr)

While True

Sockets.Clear()
Sockets.Add(m_Socket)
' Should pause here for 5s when no data, but doesn't.
Socket.Select(Sockets, Nothing, Nothing, 5000)
If Sockets.Count > 0 Then

m_Socket.Receive(Buffer, 512, SocketFlags.None)

' Process packet and send any replies, etc.

End If

' Do other book keeping tasks here.

End While

End Sub

I've also written a quick C sample to do a similar think incase it was some problem with UDP sockets, but the C version works - it pauses for 5s when there's no data to read;

#include <windows.h>
#include <winsock.h>

int _tmain(int argc, _TCHAR* argv[])
{

SOCKET m_Socket;
sockaddr_in BindAddr;
int FromLen;
sockaddr_in FromAddr;

char Buffer[ 512 ];

fd_set Sockets;

timeval Wait = { 5, 0 };

WORD wVersionRequested;
WSADATA wsaData;

wVersionRequested = MAKEWORD( 2, 2 );
WSAStartup( wVersionRequested, &wsaData );

m_Socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );

BindAddr.sin_family = AF_INET;
BindAddr.sin_addr.s_addr = inet_addr( "192.168.130.67" );
BindAddr.sin_port = htons( 5000 );
bind( m_Socket, (SOCKADDR*)&BindAddr, sizeof( BindAddr ) );

while( true )
{

FD_ZERO( &Sockets );
FD_SET( m_Socket, &Sockets );
// Correctly waits here for 5s.
if( select( 0, &Sockets, NULL, NULL, &Wait ) > 0 )
{
FromLen = sizeof( FromAddr );
recvfrom( m_Socket, Buffer, sizeof( Buffer ), 0, (SOCKADDR*)&FromAddr, &FromLen );
printf( "READ" );
// Process packet and send any replies, etc
}

// Book keeping stuff here.

}

closesocket( m_Socket );

return 0;
}

Any thoughts on why the VB version doesn't work I'd have thought it just wraps the standard API Select call, so should work, but doesn't seem too. Some property I'm missing

Thanks in advance.


Re: .NET Framework Networking and Communication Socket.Select ignores timeout and returns immediately.

Alan J. McFarlane

Any chance the VB version returns after 5ms

From MSDN:

Socket.Select(checkRead, checkWrite, checkError, microSeconds)

note the "microSeconds". :-)






Re: .NET Framework Networking and Communication Socket.Select ignores timeout and returns immediately.

RizwanSharp

OhGod wrote:

From what I've always understood of Select, and what the documentation says, it should sleep for up to the time out (5s here) waiting for data, but it doesn't. It just returns immediately whether there's data or not - though the collection is empty when there's no data so that part of it is correct.

Not 5 Seconds but 5 Micro Seconds, See MSDN documenation again.

I hope this will help.

Best Regards,

Rizwan aka RizwanSharp






Re: .NET Framework Networking and Communication Socket.Select ignores timeout and returns immediately.

OhGod

*cough* Uh..yeah, that'll be it. I read it as milliseconds, not microseconds, for some reason, hence the 5000 for a 5 second delay. Fixed now, cheers.




Re: .NET Framework Networking and Communication Socket.Select ignores timeout and returns immediately.

Anthony Bellissimo

I have the same problem, with UDP sockets and infinite timeout. Here's the snippet:

Code Snippet

// m_Sockets is List<Socket>

System.Collections.IList listen_list = new System.Collections.ArrayList(m_Sockets.ToArray());

Console.WriteLine("Before select list size: " + listen_list.Count);
Socket.Select(listen_list, null, null, -1);
Console.WriteLine("After select list size: " + listen_list.Count);



I get "After select list size: 0" and full CPU utilization if I don't put my lousy workaround in (sleeping for a bit if the list size is 0). Shouldn't the list size always be > 0 with infinite timeout




Re: .NET Framework Networking and Communication Socket.Select ignores timeout and returns immediately.

SuitedPair

I have exactly the same problem. I'd love to know why the -1 timeout value does not work as documented. I've resorted to putting the whole thing in a loop with a ridiculously long delay.

Do

' Clear the select lists

RRL.Clear()

ERL.Clear()

' Add all connections to the select lists

RRL.AddRange(_ConnReg.GetConnectionList())

ERL.AddRange(RRL)

' Monitor sockets for accept-ready/read-ready and error conditions

' Note: The docs say a timeout of '-1' waits forever. However, it lies

Socket.Select(RRL, Nothing, ERL, 1000000000)

Loop While RRL.Count = 0 And ERL.Count = 0 And Not _Abort





Re: .NET Framework Networking and Communication Socket.Select ignores timeout and returns immediately.

Alan J. McFarlane

Yup, looks like a bug. Someone should open a bug at http://connect.microsoft.com/.... I've stepped through the code with windbg and so I'll do it unless anyone beats me to it. Winsock's select[1] says "If time-out is a null pointer, select will block indefinitely", however in the -1 case Socket.Select incorrectly passes a reference to a timeval struct (which has a zero timeout value).

[1] "select (Windows)" http://msdn2.microsoft.com/en-us/library/ms740141.aspx






Re: .NET Framework Networking and Communication Socket.Select ignores timeout and returns immediately.

Alan J. McFarlane

I've created a bug at connect.microsoft.com. See https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx FeedbackID=286646 Add your votes, validation, and comments to it.




Re: .NET Framework Networking and Communication Socket.Select ignores timeout and returns immediately.

Alan J. McFarlane

The bug has been verified:

Thanks for your feedback. We have reproduced this bug on OrcasBeta1VSTS, and we are sending this bug to the appropriate group within the Visual Studio Product Team for triage and resolution. Thank you, Visual Studio Product Team.
Posted by Microsoft on 10/07/2007 at 01:42

So how quick till it is fixed... Will it make Orcas release