Переписанный код на c++/cli
Рабочий вариант
This commit is contained in:
parent
9f0faac821
commit
c6f2acf140
Binary file not shown.
@ -49,7 +49,20 @@ namespace DroneSimulator
|
||||
|
||||
~NetClient()
|
||||
{
|
||||
// Вызываем 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)
|
||||
@ -83,15 +96,16 @@ namespace DroneSimulator
|
||||
receiveData->Size = ServerData::size;
|
||||
receiveData->Server = ServerSocket;
|
||||
|
||||
ServerSocket->BeginReceive(DataServer->buffer, 0, ServerData::size,
|
||||
SocketFlags::None, gcnew AsyncCallback(this, &NetClient::ReadCallback), receiveData);
|
||||
ServerSocket->BeginReceive(DataServer->buffer, 0, ServerData::size, SocketFlags::None, gcnew AsyncCallback(this, &NetClient::ReadCallback), receiveData);
|
||||
|
||||
return ClientState::Connected;
|
||||
}
|
||||
catch (Exception^)
|
||||
{
|
||||
if (ServerSocket != nullptr)
|
||||
{
|
||||
ServerSocket->Close();
|
||||
}
|
||||
return ClientState::Error;
|
||||
}
|
||||
}
|
||||
@ -129,38 +143,114 @@ namespace DroneSimulator
|
||||
|
||||
void ReadCallback(IAsyncResult^ ar)
|
||||
{
|
||||
ReceiveData^ cd = safe_cast<ReceiveData^>(ar->AsyncState);
|
||||
if (cd == nullptr) return;
|
||||
|
||||
int bytes = 0;
|
||||
try { bytes = ServerSocket->EndReceive(ar); }
|
||||
catch (...) {}
|
||||
|
||||
if (bytes == 0)
|
||||
{
|
||||
Disconnect();
|
||||
|
||||
if (ConnectionCallback != nullptr)
|
||||
{
|
||||
ConnectData^ disconnectData = gcnew ConnectData();
|
||||
disconnectData->Connect = false;
|
||||
disconnectData->Server = nullptr;
|
||||
ConnectionCallback(disconnectData);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReceiveCallback != nullptr)
|
||||
{
|
||||
ReceiveCallback(cd);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ServerSocket->BeginReceive(cd->Buffer, 0, ServerData::size,
|
||||
SocketFlags::None, gcnew AsyncCallback(this, &NetClient::ReadCallback), cd);
|
||||
// Проверка на null входного параметра
|
||||
if (ar == nullptr) return;
|
||||
|
||||
// Безопасное приведение типа
|
||||
ReceiveData^ cd = dynamic_cast<ReceiveData^>(ar->AsyncState);
|
||||
if (cd == nullptr || ServerSocket == nullptr || !ServerSocket->Connected)
|
||||
{
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
int bytes = 0;
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
Disconnect();
|
||||
|
||||
if (ConnectionCallback != nullptr)
|
||||
{
|
||||
ConnectData^ disconnectData = gcnew ConnectData();
|
||||
disconnectData->Connect = false;
|
||||
disconnectData->Server = nullptr;
|
||||
ConnectionCallback(disconnectData);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Вызов callback получения данных
|
||||
if (ReceiveCallback != nullptr && cd->Buffer != nullptr)
|
||||
{
|
||||
try
|
||||
{
|
||||
ReceiveCallback(cd);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
System::Diagnostics::Debug::WriteLine(
|
||||
"ReceiveCallback error: " + ex->Message);
|
||||
}
|
||||
}
|
||||
|
||||
// Продолжаем прием данных
|
||||
if (ServerSocket != nullptr && ServerSocket->Connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
IAsyncResult^ result = ServerSocket->BeginReceive(
|
||||
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 (...) {}
|
||||
}
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user