This commit is contained in:
2025-04-04 00:05:34 +03:00
parent 994b0f8712
commit 9f0faac821
5 changed files with 237 additions and 6 deletions

166
DroneClientCpp/NetClient.h Normal file
View File

@ -0,0 +1,166 @@
// NetClient.h
#pragma once
#include <Windows.h>
#include <vcclr.h>
#using <System.dll>
#using <System.Net.dll>
using namespace System;
using namespace System::Net;
using namespace System::Net::Sockets;
using namespace System::Runtime::InteropServices;
namespace DroneSimulator
{
public ref class NetClient
{
public:
// Вложенный класс для данных подключения
ref class ConnectData
{
public:
property bool Connect;
property Socket^ Server;
};
// Вложенный класс для данных приема
ref class ReceiveData
{
public:
property array<Byte>^ Buffer;
property int Size;
property Socket^ Server;
};
// Состояния клиента
enum class ClientState { Error, Connected, Stop };
// Делегат для callback-функций
delegate void ClientCallback(Object^ o);
NetClient()
{
Connected = false;
ServerSocket = nullptr;
DataServer = gcnew ServerData();
}
~NetClient()
{
Close();
}
ClientState Connect(String^ addr, int port, ClientCallback^ connectionCallback, ClientCallback^ receiveCallback)
{
if (Connected)
{
Disconnect();
return ClientState::Stop;
}
ConnectionCallback = connectionCallback;
ReceiveCallback = receiveCallback;
try
{
IPEndPoint^ ep = gcnew IPEndPoint(IPAddress::Parse(addr), port);
ServerSocket = gcnew Socket(AddressFamily::InterNetwork, SocketType::Stream, ProtocolType::Tcp);
ServerSocket->Connect(ep);
Connected = true;
// Уведомление о подключении
ConnectData^ connectData = gcnew ConnectData();
connectData->Connect = true;
connectData->Server = ServerSocket;
ConnectionCallback(connectData);
// Начало приема данных
ReceiveData^ receiveData = gcnew ReceiveData();
receiveData->Buffer = DataServer->buffer;
receiveData->Size = ServerData::size;
receiveData->Server = ServerSocket;
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;
}
}
void Close()
{
Disconnect();
}
private:
ref class ServerData
{
public:
static const int size = 1024;
array<Byte>^ buffer = gcnew array<Byte>(size);
};
bool Connected;
Socket^ ServerSocket;
ServerData^ DataServer;
ClientCallback^ ConnectionCallback;
ClientCallback^ ReceiveCallback;
void Disconnect()
{
if (ServerSocket != nullptr)
{
try { ServerSocket->Shutdown(SocketShutdown::Both); }
catch (...) {}
ServerSocket->Close();
ServerSocket = nullptr;
}
Connected = false;
}
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);
}
catch (...) {}
}
};
}