148 lines
4.2 KiB
C++
148 lines
4.2 KiB
C++
#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;
|
||
|
||
namespace DroneSimulator {
|
||
|
||
public ref class NetClient
|
||
{
|
||
public:
|
||
ref class ConnectData
|
||
{
|
||
public:
|
||
bool Connect;
|
||
Socket^ Server;
|
||
|
||
// Добавлен конструктор
|
||
ConnectData(bool connect, Socket^ server)
|
||
{
|
||
Connect = connect;
|
||
Server = server;
|
||
}
|
||
};
|
||
|
||
ref class ReceiveData
|
||
{
|
||
public:
|
||
array<Byte>^ Buffer;
|
||
int Size;
|
||
Socket^ Server;
|
||
|
||
// Добавлен конструктор
|
||
ReceiveData(array<Byte>^ buffer, int size, Socket^ server)
|
||
{
|
||
Buffer = buffer;
|
||
Size = size;
|
||
Server = server;
|
||
}
|
||
};
|
||
|
||
private:
|
||
ref class ServerData
|
||
{
|
||
public:
|
||
literal int size = 1024;
|
||
array<Byte>^ buffer = gcnew array<Byte>(size);
|
||
};
|
||
|
||
bool Connected = false;
|
||
Socket^ ServerSocket = nullptr;
|
||
ServerData^ DataServer = gcnew ServerData();
|
||
|
||
public:
|
||
delegate void ClientCallback(Object^ o);
|
||
private:
|
||
ClientCallback^ ConnectionCallback;
|
||
ClientCallback^ ReceiveCallback;
|
||
|
||
public:
|
||
enum class ClientState { Error, Connected, Stop };
|
||
|
||
ClientState Connect(String^ Addr, int Port, ClientCallback^ Connection, ClientCallback^ Receive)
|
||
{
|
||
if (Connected)
|
||
{
|
||
Close();
|
||
return ClientState::Stop;
|
||
}
|
||
|
||
ConnectionCallback = Connection;
|
||
ReceiveCallback = Receive;
|
||
|
||
IPEndPoint^ ep = gcnew IPEndPoint(IPAddress::Parse(Addr), Port);
|
||
ServerSocket = gcnew Socket(AddressFamily::InterNetwork, SocketType::Stream, ProtocolType::Tcp);
|
||
|
||
try { ServerSocket->Connect(ep); }
|
||
catch (...) { ServerSocket->Close(); return ClientState::Error; }
|
||
|
||
Connected = true;
|
||
|
||
// Исправленный вызов с конструктором
|
||
ConnectionCallback(gcnew ConnectData(true, ServerSocket));
|
||
|
||
// Исправленный вызов с конструктором
|
||
ReceiveData^ receiveData = gcnew ReceiveData(DataServer->buffer, ServerData::size, ServerSocket);
|
||
|
||
try { ServerSocket->BeginReceive(DataServer->buffer, 0, ServerData::size, SocketFlags::None, gcnew AsyncCallback(this, &NetClient::ReadCallback), receiveData); }
|
||
catch (...) {}
|
||
|
||
return ClientState::Connected;
|
||
}
|
||
|
||
void Close()
|
||
{
|
||
try { ServerSocket->Shutdown(SocketShutdown::Both); }
|
||
catch (...) {}
|
||
ServerSocket->Close();
|
||
Connected = false;
|
||
}
|
||
|
||
void Send(array<Byte>^ data)
|
||
{
|
||
if (ServerSocket != nullptr && Connected)
|
||
{
|
||
try { ServerSocket->Send(data); }
|
||
catch (...) {}
|
||
}
|
||
}
|
||
|
||
private:
|
||
void ReadCallback(IAsyncResult^ ar)
|
||
{
|
||
ReceiveData^ cd = (ReceiveData^)ar->AsyncState;
|
||
if (cd == nullptr) return;
|
||
|
||
int bytes = 0;
|
||
try { bytes = ServerSocket->EndReceive(ar); }
|
||
catch (...) {}
|
||
|
||
if (bytes == 0)
|
||
{
|
||
ServerSocket->Close();
|
||
Connected = false;
|
||
|
||
if (ServerSocket != nullptr)
|
||
{
|
||
// Исправленный вызов с конструктором
|
||
ConnectionCallback(gcnew ConnectData(false, nullptr));
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
// Исправленный вызов с конструктором
|
||
ReceiveCallback(gcnew ReceiveData(cd->Buffer, bytes, ServerSocket));
|
||
|
||
try { ServerSocket->BeginReceive(cd->Buffer, 0, ServerData::size, SocketFlags::None, gcnew AsyncCallback(this, &NetClient::ReadCallback), cd); }
|
||
catch (...) {}
|
||
}
|
||
};
|
||
} |