I am developing a UDP server that sends a time value over LAN to clients that periodically query the server every 250ms. There is an alarm that sounds when the time hits zero on the client-end, so all clients must receive the message at as close to the same time as possible.
To make this happen, I have a listening function that listens for clients and pushes their endpoints to a queue.
Every 250ms with a System.Windows.Forms.Timer, each client is sent the current time value and their endpoint dequeued.
Problem: the server application unpredictably freezes every so often. Both the server and client applications can be closed and opened with no problems. Sometimes the server will run just fine for days at a time and then just suddenly freeze.
My attempted solutions: try + catching and using() anything that has to do with a socket, adding send and receive timeouts for all sockets depending on their function. Would switching to a TCP protocol better suit this use case?
Inside server form load:
this.clientEPs = new Queue<IPEndPoint>();
Thread listener = new Thread(this.listen);
listener.IsBackground = true;
listener.Start();
timer.Start();
Server listening thread:
private void listen()
{
IPEndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
try
{
using (UdpClient listener = new UdpClient(LISTENPORT))
{
listener.Client.ReceiveTimeout = 1000;
try
{
while (true)
{
listener.Receive(ref clientEP);
this.mutex.WaitOne();
this.clientEPs.Enqueue(clientEP);
this.mutex.ReleaseMutex();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
listener.Close();
}
}
}
catch (Exception exc)
{
Console.WriteLine(exc.ToString());
}
}
}
Server relay function:
private void relay()
{
this.mutex.WaitOne();
try
{
using (UdpClient relayer = new UdpClient(RELAYPORT))
{
relayer.Client.SendTimeout = 1000;
try
{
while (this.clientEPs.Count > 0)
{
relayer.Send(this.messageBytes, this.messageBytes.Length, this.clientEPs.Peek());
this.clientEPs.Dequeue();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
relayer.Close();
}
}
}
catch (Exception exc)
{
Console.WriteLine(exc.ToString());
}
this.mutex.ReleaseMutex();
}
Server relay ticker:
private void timer_Tick(object sender, EventArgs e)
{
string message = DateTime.Now.ToString();
this.messageBytes = Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(message));
this.relay();
}
Client initalization in form load.
Thread communicator = new Thread(this.communicate);
communicator.IsBackground = true;
communicator.Start();
this.time = new string();
Client query thread:
private void communicate()
{
IPEndPoint serverEP = new IPEndPoint(IPAddress.Any, 0);
string serverMessage;
byte[] clientMessage = Encoding.Unicode.GetBytes("Please send the current time.");
while (true)
{
try
{
using (UdpClient client = new UdpClient(CLIENTPORT))
{
try
{
client.Client.SendTimeout = 1000;
client.Client.ReceiveTimeout = 1000;
while (true)
{
client.Send(clientMessage, clientMessage.Length, SERVERIP, SERVERPORT);
serverMessage = Encoding.Unicode.GetString(client.Receive(ref serverEP));
this.currentTime = serverMessage;
if (message == null)
throw new Exception();
if (isTimeZero(this.currentTime))
{
SoundPlayer sp = new SoundPlayer("resources\audio\BEEP.wav");
sp.Play();
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
client.Close();
Thread.Sleep(250);
}
}
}
catch (Exception exc)
{
Console.WriteLine(exc.ToString());
}
}
}
P.S. I am a newbie to networking in general and any critiques/advice would be greatly appreciated! Thank you!
question from:
https://stackoverflow.com/questions/65920116/udp-server-freezes