Переписанный код на c++/cli

Рабочий вариант
This commit is contained in:
Dizel 2025-04-04 11:49:03 +03:00
parent 9f0faac821
commit c6f2acf140
2 changed files with 121 additions and 31 deletions

Binary file not shown.

View File

@ -49,7 +49,20 @@ namespace DroneSimulator
~NetClient() ~NetClient()
{ {
// Вызываем Close() для корректного закрытия соединения
Close(); Close();
// Дополнительная очистка ресурсов
if (DataServer != nullptr)
{
// Очищаем буфер данных
DataServer->buffer = nullptr;
DataServer = nullptr;
}
// Обнуляем callback-делегаты
ConnectionCallback = nullptr;
ReceiveCallback = nullptr;
} }
ClientState Connect(String^ addr, int port, ClientCallback^ connectionCallback, ClientCallback^ receiveCallback) ClientState Connect(String^ addr, int port, ClientCallback^ connectionCallback, ClientCallback^ receiveCallback)
@ -83,15 +96,16 @@ namespace DroneSimulator
receiveData->Size = ServerData::size; receiveData->Size = ServerData::size;
receiveData->Server = ServerSocket; receiveData->Server = ServerSocket;
ServerSocket->BeginReceive(DataServer->buffer, 0, ServerData::size, ServerSocket->BeginReceive(DataServer->buffer, 0, ServerData::size, SocketFlags::None, gcnew AsyncCallback(this, &NetClient::ReadCallback), receiveData);
SocketFlags::None, gcnew AsyncCallback(this, &NetClient::ReadCallback), receiveData);
return ClientState::Connected; return ClientState::Connected;
} }
catch (Exception^) catch (Exception^)
{ {
if (ServerSocket != nullptr) if (ServerSocket != nullptr)
{
ServerSocket->Close(); ServerSocket->Close();
}
return ClientState::Error; return ClientState::Error;
} }
} }
@ -129,13 +143,45 @@ namespace DroneSimulator
void ReadCallback(IAsyncResult^ ar) void ReadCallback(IAsyncResult^ ar)
{ {
ReceiveData^ cd = safe_cast<ReceiveData^>(ar->AsyncState); try
if (cd == nullptr) return; {
// Проверка на null входного параметра
if (ar == nullptr) return;
// Безопасное приведение типа
ReceiveData^ cd = dynamic_cast<ReceiveData^>(ar->AsyncState);
if (cd == nullptr || ServerSocket == nullptr || !ServerSocket->Connected)
{
Disconnect();
return;
}
int bytes = 0; int bytes = 0;
try { bytes = ServerSocket->EndReceive(ar); } try
catch (...) {} {
bytes = ServerSocket->EndReceive(ar);
}
catch (ObjectDisposedException^)
{
// Сокет был закрыт
Disconnect();
return;
}
catch (SocketException^ ex)
{
// Логирование ошибки сокета
System::Diagnostics::Debug::WriteLine(
"Socket receive error: " + ex->Message);
Disconnect();
return;
}
catch (...)
{
Disconnect();
return;
}
// Проверка на разрыв соединения
if (bytes == 0) if (bytes == 0)
{ {
Disconnect(); Disconnect();
@ -150,17 +196,61 @@ namespace DroneSimulator
return; return;
} }
if (ReceiveCallback != nullptr) // Вызов callback получения данных
if (ReceiveCallback != nullptr && cd->Buffer != nullptr)
{
try
{ {
ReceiveCallback(cd); ReceiveCallback(cd);
} }
catch (Exception^ ex)
{
System::Diagnostics::Debug::WriteLine(
"ReceiveCallback error: " + ex->Message);
}
}
// Продолжаем прием данных
if (ServerSocket != nullptr && ServerSocket->Connected)
{
try try
{ {
ServerSocket->BeginReceive(cd->Buffer, 0, ServerData::size, IAsyncResult^ result = ServerSocket->BeginReceive(
SocketFlags::None, gcnew AsyncCallback(this, &NetClient::ReadCallback), cd); cd->Buffer,
0,
ServerData::size,
SocketFlags::None,
gcnew AsyncCallback(this, &NetClient::ReadCallback),
cd);
// Проверка на ошибку асинхронной операции
if (result == nullptr)
{
Disconnect();
}
}
catch (ObjectDisposedException^)
{
Disconnect();
}
catch (SocketException^ ex)
{
System::Diagnostics::Debug::WriteLine(
"BeginReceive error: " + ex->Message);
Disconnect();
}
catch (...)
{
Disconnect();
}
}
}
catch (Exception^ ex)
{
System::Diagnostics::Debug::WriteLine(
"ReadCallback general error: " + ex->Message);
Disconnect();
} }
catch (...) {}
} }
}; };
} }