Is there a way to poll a socket in C# only when something is available for reading?
Asked Answered
O

6

5

I'm wondering whether there is a way to poll a socket in c# when only one of the conditions (data is available for reading) is satisfied, I'm aware of the socket.Poll method but this can return true if any number of the 3 conditions specified returns true as specified here: MSDN: Socket.Poll

Overhappy answered 8/8, 2009 at 19:3 Comment(0)
O
8

According to the MSDN documentation there are three causes that return true for

Poll(microSeconds, SelectMode.SelectRead);

  1. if Listen() has been called and a connection is pending
  2. If data is available for reading
  3. If the connection has been closed, reset, or terminated

Let's see if we can discriminate them:

  1. You always know if Listen() has been called before, so you don't need to consider that cause if you have not.
  2. Ok, you go for that.
  3. Means that you can not stay in the Poll() call and need to find out what really happened. One option is to check the socket's state immediately after Poll() returned.

Conclusion:

  1. needs not to be considered

  2. and 3. can be handled by checking the socket state each time true is returned.

So I would go for (untested):

if (s.Poll(microSeconds, SelectMode.SelectRead)))
{
  if (!s.Connected)
    // Something bad has happened, shut down
  else
    // There is data waiting to be read"
}
Onestep answered 9/8, 2009 at 8:25 Comment(2)
Thank you all for your response.Overhappy
You should check Connected before calling poll or poll for Write first before reading as that is what Connected does under the hood anyways.Crossbar
F
5

You could use Socket property Available. It returns how much data is available to read.

Ferrari answered 9/8, 2009 at 7:57 Comment(0)
A
1

Found something in class NetworkStream. Property NetworkStream.DataAvailable returns true if data is available for reading. Object of networkstream is returned dealing with TcpListener and TcpClient. This is one abstraction level higher than socket.

I found no way to come from Socket to NetworkStream. A NetworkStream is using a socket and is the stream representation of a socket. But I dont know what the networkstream is doing there with the socket.

Adultery answered 8/8, 2009 at 20:39 Comment(1)
NetworkStream also has .CanRead and .CanWrite which I have found very useful.Stacistacia
P
1

You could use the select() system call on the underlying handle.

Parget answered 8/8, 2009 at 20:40 Comment(1)
My first thought too, but not shure if this is what dark-star really means.Adultery
M
1

You can use Select() method instead of Poll(). Actually when looking into Socket.Poll with ILSpy (reflector tool) the internal code is calling select on the socket.

In addition, calling Poll() in a tight loop will increase memory allocation as it does a new IntPtr[] on each call. Calling Select() lets you reuse the arrays instead of allocating new ones under the hood.

Melodist answered 19/5, 2014 at 12:30 Comment(0)
F
0

true if Listen has been called and a connection is pending; -or- true if data is available for reading; -or- true if the connection has been closed, reset, or terminated; otherwise, returns false.

I understand that you want to check if the second option is the one returning true? After checking if the Poll returns true, you can check if the connection is open, that means; not connection, closed, reset or terminated.

If it is open, then it's the second option return true.

Felicidadfelicie answered 8/8, 2009 at 20:49 Comment(1)
like: if (m_sock.Poll(-1, SelectMode.SelectRead) && (m_sock.Connected == true)) ?Overhappy

© 2022 - 2024 — McMap. All rights reserved.