Dizel 26fc24ae0d Переписанная рабочая версия
Переделал код c++/cli на новый лад как в c# client
2025-04-09 15:49:27 +03:00

148 lines
4.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 (...) {}
}
};
}