Introduce DataBase,Asp.net,JavaScript,Xml,Html,Css,Sql,Php,ASP.NET Controls,AJAX,Tools,HTML,CSS,JavaScript,Open Source Project,WPF,.Net Framework,Linq
Top Recommended Hosting

Networking and Communication Socket.Select ignores timeout and returns immediately.

by the3factory 4/9/2008 1:39:00 AM
Networking and Communication Socket.Select ignores timeout and returns immediately.
Question:
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.

Answer1:

Any chance the VB version returns after 5ms?

From MSDN:

    Socket.Select

Answer2:

 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




WPF Learning Series @ http://geekswithblogs.net/RizwanSharp :: Microsoft MVP - Visual Developer, C#
Answer3:
*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.
Answer4:
I have the same problem, with UDP sockets and infinite timeout. Here's the snippet:

Code Snippet
Answer5:

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

 

Answer6:

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




http://www.alanjmcf.me.uk/ Please follow-up in the newsgroup. If I help, mark the question answered
Answer7:
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.




http://www.alanjmcf.me.uk/ Please follow-up in the newsgroup. If I help, mark the question answered
Answer8:

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?




http://www.alanjmcf.me.uk/ Please follow-up in the newsgroup. If I help, mark the question answered
Answer9:
Still doesn't look like there's a fix. I've installed 3.5 and my code still fails to Select correctly on infinity. Debugging their code shows that it is still using an uninitialised TimeValue.

Anyone got any ideas?

FYI who noticed the workaround on the connect website, they suggest passing -2 for a value of >1 hour Indifferent

Related posts

Sign up for PayPal and start accepting credit card payments instantly.


Powered by BlogEngine.NET 1.2.0.0