Hi
I have a small program listening to UDP broadcast datagrams that are
periodically sent out. It will stop listening for a certain period if either
a sufficient number of packets has been received (this is triggered from a
class not in the sample code), or if there has been no data on the net for a
certain period. During the time where I don't want any packets, I set my
socket receive buffer size to zero.
The problem is, when I used a UDPClient, I was always getting data that was
sent during the period where no listening took place (and changing the
buffer size didn't help), so I'm using sockets directly. However, I don't
receive a single packet now and I have no clue why. sock.Available is always
zero, even if I send a thousand UDP datagrams during the active period.
Here's my code:
public class Receiver
{
IPEndPoint remoteSender;
EndPoint tempRemoteEP;
byte[] packet;
public Thread thread;
bool listening;
Timer tim;
TimerState s;
public int nbPackets;
int seqNo;
Socket sock;
int nbBytesRx;
public Receiver()
{
sock = new Socket(AddressF amily.InterNetw ork, SocketType.Dgra m,
ProtocolType.Ud p);
sock.SetSocketO ption(SocketOpt ionLevel.Socket ,
SocketOptionNam e.Broadcast, 1);
remoteSender = new IPEndPoint(IPAd dress.Any,0);
tempRemoteEP = (EndPoint)remot eSender;
sock.SetSocketO ption(SocketOpt ionLevel.Socket ,
SocketOptionNam e.ReceiveBuffer , 0);
listening = false;
nbPackets = 0;
packet = new byte[1024];
s = new TimerState();
TimerCallback timerDelegate = new TimerCallback(t his.timeToSleep );
tim = new Timer(timerDele gate, null, Timeout.Infinit e, Timeout.Infinit e);
ThreadStart startMethod = new ThreadStart(thi s.run);
thread = new Thread(startMet hod);
thread.Start();
thread.Suspend( );
}
/**
* method that is running when the thread is active
* receives a packet from the network and processes it
*/
public void run()
{
while (true)
{
if (sock.Available > 0)
{
this.nbBytesRx = sock.ReceiveFro m(packet, ref tempRemoteEP);
nbPackets++;
seqNo = BitConverter.To Int16(packet, 0);
Console.Write(n bPackets.ToStri ng() + ":" + seqNo.ToString( ) + " / " );
}
}
}
/**
* resumes the thread
*/
public void activate()
{
if (thread.ThreadS tate == ThreadState.Sus pended || thread.ThreadSt ate ==
ThreadState.Sus pendRequested)
{
Console.WriteLi ne("activated") ;
tim.Change(5000 , 5000);
if (sock.Available > 0)
{
Console.Write(" pending data");
}
sock.SetSocketO ption(SocketOpt ionLevel.Socket ,
SocketOptionNam e.ReceiveBuffer , 8192);
thread.Resume() ;
}
else
{
Console.WriteLi ne("thread was already running");
}
this.listening = true;
}
/**
* suspends the thread
*/
public void deactivate()
{
if (thread.ThreadS tate == ThreadState.Run ning)
{
Console.WriteLi ne("\r\ndeactiv ated. " + this.nbPackets. ToString() + "
packets received");
tim.Change(Time out.Infinite,Ti meout.Infinite) ; // disable timer for the
time being
sock.SetSocketO ption(SocketOpt ionLevel.Socket ,
SocketOptionNam e.ReceiveBuffer , 0);
thread.Suspend( );
}
else
{
Console.WriteLi ne("thread was already inactive");
}
this.listening = false;
this.nbPackets = 0;
}
public void shutDown()
{
if (thread.ThreadS tate == ThreadState.Sus pended)
thread.Resume() ;
thread.Abort();
}
/**
* Callback for the timer. Checks whether it's time to suspend the thread
because no new packets
* are coming in
*/
public void timeToSleep(Obj ect state)
{
//TimerState stat = (TimerState)sta te;
if (this.nbPackets > s.counter) // new packets received in current period
{
s.counter = this.nbPackets;
}
else
{
if (this.listening )
{
this.deactivate ();
s.counter = 0;
}
}
}
}
public struct TimerState
{
public int counter;
public Timer tim;
}
and to test I use this code which periodically activates and deactivates the
receiver.
static void Main(string[] args)
{
Receiver rec = new Receiver();
while (true)
{
rec.activate();
Thread.Sleep(10 000);
rec.deactivate( );
Thread.Sleep(10 000);
}
}
Any help would be much appreciated.
Regards
Stephan Steiner