#c# #tcp #tcpclient #tcplistener
#c# #tcp #tcpclient #tcplistener
Вопрос:
У меня есть небольшое приложение WinForm. Все, что он делает, это считывает сообщение, полученное в буфере. Если сообщение соответствует ожидаемому ключевому слову, оно увеличивает число, отображаемое в главном окне, и выводит сообщение в отдельном окне сообщений. Брандмауэр выключен, антивирус или брандмауэр сторонних производителей не установлены, операционная система — Windows Server 2019 Datacenter (ver1809).
Он работает отлично, но через 2-3 часа происходит сбой.
Program.cs:
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
namespace SocketTestApp
{
static class Program
{
private static SocketTestAppReciever app;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
app=new SocketTestAppReciever();
app.ShowIcon = false;
try
{
Application.Run(app);
}
catch (Exception ex)
{
MessageBox.Show(ExceptionToString(ex));
app.BackColor = System.Drawing.Color.Red;
Environment.Exit(1);
}
}
public static string ExceptionToString(Exception ex)
{
string result = "";
string tab = "";
result = "-----------------------------------------------------------------------------n";
result = ('n');
while (ex != null)
{
result = tab (ex.GetType().FullName) 'n';
result = tab ("Message : " ex.Message) 'n';
result = tab ("StackTrace : " ex.StackTrace) 'n';
result = tab ("TargetSite : " ex.TargetSite.ToString()) 'n';
ex = ex.InnerException;
tab = " ";
}
result = "n-----------------------------------------------------------------------------n";
return resu<
}
public static void StartListener()
{
IPAddress ip = null;
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress _ip in host.AddressList)
{
if (_ip.AddressFamily == AddressFamily.InterNetwork)
{
ip = _ip;
}
}
if (ip is null)
{
MessageBox.Show("IP is null,exiting", "TestApp StartListener Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
Environment.Exit(1);
}
TcpListener server = new TcpListener(ip, 8081);
try
{
server.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "TestApp StartListener Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
Environment.Exit(1);
}
while (true)
{
TcpClient client = server.AcceptTcpClient();
NetworkStream stream = client.GetStream();
try
{
if (stream.CanRead)
{
byte[] myReadBuffer = new byte[100];
StringBuilder myCompleteMessage = new StringBuilder();
int numberOfBytesRead = 0;
// Incoming message may be larger than the buffer size.
do
{
numberOfBytesRead = stream.Read(myReadBuffer, 0, myReadBuffer.Length);
myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
}
while (stream.DataAvailable);
if (app.ShowEveryMsgInBox) { MessageBox.Show(myCompleteMessage.ToString(), "Message recieved", MessageBoxButtons.OK); }
if (myCompleteMessage.ToString() == "LIQUIDATE"){app.IncreaseNumber();
}
}
else
{
MessageBox.Show("Sorry. You cannot read from this NetworkStream.", "TestApp StartListener Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
Environment.Exit(1);
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString(), "TestApp StartListener error inside wile loop", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
Environment.Exit(1);
}
finally{stream.Close();}
}
}
}
}
Form1.cs:
using System;
using System.Windows.Forms;
using System.Threading;
namespace SocketTestApp
{
public partial class SocketTestAppReciever : Form
{
public bool ShowEveryMsgInBox=false;
public SocketTestAppReciever()
{
InitializeComponent();
ShowEveryMsgInBox_checkBox1.CheckedChanged = CheckedChange;
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
Program.StartListener();
}).Start();
}
private void CheckedChange(object sender, EventArgs e)
{
ShowEveryMsgInBox = ((CheckBox)sender).Checked;
}
public void IncreaseNumber()
{
this.Invoke((MethodInvoker)delegate
{
label1.Text = (Int32.Parse(this.label1.Text) 1).ToString();
});
}
}
}
Сообщение об ошибке:
Сообщение System.IO.IOException : не удалось прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто удаленным хостом. StackTrace : в System.Net.Sockets.NetworkStream.Read(буфер байт [], смещение Int32, размер Int32) в SocketTestApp.Program.d__5.MoveNext()
Целевой сайт: чтение Int32 (байт [], Int32, Int32) System.Net.Sockets.Исключение SocketException
Сообщение: существующее соединение было принудительно закрыто удаленным хостом
StackTrace : в System.Net.Sockets.NetworkStream.Read(буфер байт [], смещение Int32, размер Int32) TargetSite: чтение Int32 (байт [], Int32, Int32)
Это то, что я нашел в EventViewer:
Ошибка в имени приложения: SocketServer.exe , версия: 1.0.0.0, отметка времени: 0xfb692933 Имя модуля сбоя: KERNELBASE.dll , версия: 10.0.17763.1518, отметка времени: 0xff301d3c Код исключения: 0xe0434352 Смещение ошибки: 0x00000000000396c9 Идентификатор процесса сбоя: 0x22064 Время запуска приложения сбоя: 0x01d6ac886ca804ae Путь к приложению сбоя: C:UserspaperspaceDesktopSocketServer.exe Путь к неисправному модулю: C:WindowsSystem32KERNELBASE.dll Идентификатор отчета:e469e9f9-8f5c-4597-8c4c-5ba4ac06c6bb Полное имя пакета с ошибкой: пакет с ошибкой -относительный идентификатор приложения:
Не могли бы вы помочь мне с проблемой? Я новичок в программировании и понятия не имею, что именно его закрыло. Является ли удаленный хост операционной системой? Или кто-то другой может просто случайно закрыть это соединение?
Комментарии:
1. Просто предположение, но может быть проблемой исчерпания порта. Поскольку вы упомянули, что программа некоторое время работает нормально, а затем выходит из строя — вероятно, ваш сервер C # или даже ОС не могут принимать больше подключений из-за некоторого ограничения
2. Имеет ли это какое-либо отношение к количеству сообщений, полученных в течение этого 2-3-часового периода? Обычно за этот период времени он получает всего 2 или 3 сообщения.