Я написал довольно простое c приложение в C# (. NET Compact Framework 2.0) с использованием сокетов UDP.
Программа работает некоторое время (до пары недель в время), но всегда терпит неудачу в конце концов. Вдобавок к тому, что мои клиенты не могут повторно подключиться, эта ошибка, кажется, отрицательно убивает активность all из соответствующего NI C. Как только это происходит, я больше не могу удаленно подключаться к устройству (используя CE Remote Display) - это мой единственный способ получить дополнительную обратную связь для отладки. Поэтому на данный момент я не уверен на 100%, происходит ли сбой самого приложения или я что-то ломаю в операционной системе через код моего сокета.
Я реализовал событие необработанного исключения, которое никогда не вызывается. У меня также есть несколько блоков try / catch, которые выводят сообщение об исключении в текстовый файл. Я не вижу каких-либо исключений.
/// Удален старый код TCP.
Сами клиенты - это простые маленькие шлюзовые устройства, которые настроены как серверы UDP. Это удаленная система, к которой я имею доступ редко, и хотя у меня есть тестовый контроллер и шлюз, условия не идентичны, и я еще не смог воспроизвести проблему на моем конце.
TIA за любые отзывы.
Редактировать:
Я работал с моей демонстрационной версией тестового стенда и периодически проверял netstat на сервере для некоторых предложений комментариев. В CE5 netstat не принимает флаг -a, поэтому я использую -n (не уверен, что это скажет мне, что мне нужно ...). Я несколько раз отключал и переподключал своих клиентов, заставляя полуоткрывать, отключая Ethe rnet, et c. и таблица netstat показывает только одно соединение для каждого клиента (на соответствующих портах).
Редактировать 2:
Из-за редкого характера обмена сообщениями во время работы я изменил приложение на UDP-обмен сообщениями без установления соединения, но я все еще испытываю такое же поведение (примерно столько же времени до отказа). На моем тестовом оборудовании приложение успешно работает бесконечно с высокой частотой сообщений (раз в несколько секунд). Однако в производстве, где сообщения будут встречаться гораздо реже, программа не будет работать после 10 дней работы. Я не думаю, что бездействие будет иметь значение, но, возможно, я ошибаюсь? Ищу любые предложения, которые я могу получить.
Новый код отправки / получения:
public void Send(string Message)
{
Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
EndPoint ep = new IPEndPoint(IPAddress.Parse(_ipAddress), _port);
udpClient.Connect(ep);
byte[] data = Encoding.ASCII.GetBytes(Message);
// async send, sync receive
udpClient.BeginSendTo(data, 0, data.Length, SocketFlags.None, ep, (ar) =>
{
try
{
udpClient.EndSendTo(ar);
_lastSent = Message;
string msg = this.ReceiveSync(udpClient, 3);
if (!string.IsNullOrEmpty(msg))
{
_lastReceived = msg;
DataReceived(new ReceiveDataEvent(_lastReceived));
}
}
catch { }
finally
{
udpClient.Close();
}
}, null);
}
private string ReceiveSync(Socket UdpClient, int TimeoutSec)
{
string msg = "";
byte[] recBuffer = new byte[256];
int elapsed = 0;
bool terminate = false;
do
{
// check for data avail every 500ms until TimeoutSecs elapsed
if (UdpClient.Available > 0)
{
int bytesRead = UdpClient.Receive(recBuffer, 0, recBuffer.Length, SocketFlags.None);
msg = Encoding.ASCII.GetString(recBuffer, 0, recBuffer.Length);
terminate = true;
}
else
{
if ((elapsed / 2) == TimeoutSec)
terminate = true;
else
{
elapsed++;
System.Threading.Thread.Sleep(500);
}
}
} while (!terminate);
return msg;
}