Переписанная рабочая версия
Переделал код c++/cli на новый лад как в c# client
This commit is contained in:
parent
1558429ad0
commit
26fc24ae0d
216
DroneClientCpp/Drone.h
Normal file
216
DroneClientCpp/Drone.h
Normal file
@ -0,0 +1,216 @@
|
||||
#pragma once
|
||||
|
||||
#include "DroneData.h"
|
||||
#include <Windows.h>
|
||||
#include <vcclr.h>
|
||||
|
||||
#using <System.dll>
|
||||
#using <mscorlib.dll>
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Collections::Generic;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
|
||||
namespace DroneClient {
|
||||
|
||||
public ref class Drone
|
||||
{
|
||||
public:
|
||||
float AccX, AccY, AccZ;
|
||||
float GyrX, GyrY, GyrZ;
|
||||
float PosX, PosY;
|
||||
float LaserRange;
|
||||
|
||||
float MotorUL, MotorUR, MotorDL, MotorDR;
|
||||
|
||||
static array<Byte>^ GetBytes(Object^ data)
|
||||
{
|
||||
int size = Marshal::SizeOf(data);
|
||||
array<Byte>^ arr = gcnew array<Byte>(size);
|
||||
|
||||
IntPtr ptr = IntPtr::Zero;
|
||||
try
|
||||
{
|
||||
ptr = Marshal::AllocHGlobal(size);
|
||||
Marshal::StructureToPtr(data, ptr, true);
|
||||
Marshal::Copy(ptr, arr, 0, size);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal::FreeHGlobal(ptr);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
static Object^ FromBytes(array<Byte>^ arr, Type^ type)
|
||||
{
|
||||
Object^ mem = gcnew Object();
|
||||
|
||||
int size = Marshal::SizeOf(type);
|
||||
IntPtr ptr = IntPtr::Zero;
|
||||
try
|
||||
{
|
||||
ptr = Marshal::AllocHGlobal(size);
|
||||
Marshal::Copy(arr, 0, ptr, size);
|
||||
mem = Marshal::PtrToStructure(ptr, type);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal::FreeHGlobal(ptr);
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
|
||||
private:
|
||||
array<Byte>^ SendDataMotor4()
|
||||
{
|
||||
DroneData::DataMotor4 mot4;
|
||||
|
||||
mot4.Head.Size = Marshal::SizeOf(DroneData::DataMotor4::typeid);
|
||||
mot4.Head.Mode = DroneData::DataMode::Response;
|
||||
mot4.Head.Type = DroneData::DataType::DataMotor4;
|
||||
|
||||
mot4.UL = MotorUL;
|
||||
mot4.UR = MotorUR;
|
||||
mot4.DL = MotorDL;
|
||||
mot4.DR = MotorDR;
|
||||
|
||||
return GetBytes(mot4);
|
||||
}
|
||||
|
||||
array<Byte>^ RecvDataIMU(array<Byte>^ data)
|
||||
{
|
||||
DroneData::DataIMU imu = (DroneData::DataIMU)FromBytes(data, DroneData::DataIMU::typeid);
|
||||
|
||||
AccX = imu.Acc.X; AccY = imu.Acc.Y; AccZ = imu.Acc.Z;
|
||||
GyrX = imu.Gyr.X; GyrY = imu.Gyr.Y; GyrZ = imu.Gyr.Z;
|
||||
|
||||
return gcnew array<Byte>(0);
|
||||
}
|
||||
|
||||
array<Byte>^ RecvDataPos(array<Byte>^ data)
|
||||
{
|
||||
DroneData::DataPos pos = (DroneData::DataPos)FromBytes(data, DroneData::DataPos::typeid);
|
||||
|
||||
PosX = pos.Local.X; PosY = pos.Local.Y;
|
||||
LaserRange = pos.LiDAR;
|
||||
|
||||
return gcnew array<Byte>(0);
|
||||
}
|
||||
|
||||
array<Byte>^ ClientRequestResponse(DroneData::DataHead head, array<Byte>^ body)
|
||||
{
|
||||
array<Byte>^ zero = gcnew array<Byte>(0);
|
||||
|
||||
switch (head.Type)
|
||||
{
|
||||
case DroneData::DataType::DataIMU:
|
||||
if (head.Mode == DroneData::DataMode::Request)
|
||||
{
|
||||
return zero; // Запрос данных (не реализовано)
|
||||
}
|
||||
else
|
||||
{
|
||||
return RecvDataIMU(body); // Пришли данные
|
||||
}
|
||||
|
||||
case DroneData::DataType::DataPos:
|
||||
if (head.Mode == DroneData::DataMode::Request)
|
||||
{
|
||||
return zero; // Запрос данных (не реализовано)
|
||||
}
|
||||
else
|
||||
{
|
||||
return RecvDataPos(body); // Пришли данные
|
||||
}
|
||||
|
||||
case DroneData::DataType::DataMotor4:
|
||||
if (head.Mode == DroneData::DataMode::Request)
|
||||
{
|
||||
return SendDataMotor4(); // Запрос данных
|
||||
}
|
||||
else
|
||||
{
|
||||
return zero; // Пришли данные (не реализовано)
|
||||
}
|
||||
}
|
||||
|
||||
return zero;
|
||||
}
|
||||
|
||||
literal int DroneStreamCount = 512;
|
||||
array<Byte>^ DroneStreamData = gcnew array<Byte>(DroneStreamCount);
|
||||
int DroneStreamIndex = 0;
|
||||
DroneData::DataHead DroneStreamHead; // Исправлено: без явной инициализации
|
||||
|
||||
public:
|
||||
// Конструктор для явной инициализации
|
||||
Drone()
|
||||
{
|
||||
DroneStreamHead.Mode = DroneData::DataMode::None;
|
||||
DroneStreamHead.Size = 0;
|
||||
DroneStreamHead.Type = DroneData::DataType::None;
|
||||
}
|
||||
|
||||
System::Collections::Generic::List<array<Byte>^>^ DataStream(array<Byte>^ data, int size)
|
||||
{
|
||||
System::Collections::Generic::List<array<Byte>^>^ ret = gcnew System::Collections::Generic::List<array<Byte>^>();
|
||||
|
||||
if (data == nullptr) return ret; // Последовательность не сформирована
|
||||
|
||||
if (size + DroneStreamIndex > DroneStreamCount) return nullptr; // Ошибка переполнения
|
||||
|
||||
Array::Copy(data, 0, DroneStreamData, DroneStreamIndex, size);
|
||||
DroneStreamIndex += size;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (DroneStreamHead.Size == 0) // Заголовок еще не получен
|
||||
{
|
||||
if (DroneStreamIndex < DroneData::DataHead::StrLen) return ret;
|
||||
DroneStreamHead = (DroneData::DataHead)FromBytes(DroneStreamData, DroneData::DataHead::typeid);
|
||||
}
|
||||
|
||||
if (DroneStreamHead.Size > DroneStreamIndex) break; // Пакет еще не полный
|
||||
|
||||
array<Byte>^ body = gcnew array<Byte>(DroneStreamHead.Size);
|
||||
Array::Copy(DroneStreamData, 0, body, 0, DroneStreamHead.Size);
|
||||
|
||||
int shift = DroneStreamHead.Size;
|
||||
|
||||
DroneStreamIndex -= shift;
|
||||
Array::Copy(DroneStreamData, shift, DroneStreamData, 0, DroneStreamIndex); // Сдвиг массива
|
||||
|
||||
DroneStreamHead.Size = 0; // Сброс заголовка
|
||||
|
||||
ret->Add(ClientRequestResponse(DroneStreamHead, body));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
array<Byte>^ SendRequest()
|
||||
{
|
||||
DroneData::DataHead imu;
|
||||
imu.Size = DroneData::DataHead::StrLen;
|
||||
imu.Mode = DroneData::DataMode::Request;
|
||||
imu.Type = DroneData::DataType::DataIMU;
|
||||
|
||||
DroneData::DataHead pos;
|
||||
pos.Size = DroneData::DataHead::StrLen;
|
||||
pos.Mode = DroneData::DataMode::Request;
|
||||
pos.Type = DroneData::DataType::DataPos;
|
||||
|
||||
array<Byte>^ si = GetBytes(imu);
|
||||
array<Byte>^ sp = GetBytes(pos);
|
||||
array<Byte>^ sm = SendDataMotor4();
|
||||
|
||||
array<Byte>^ send = gcnew array<Byte>(si->Length + sp->Length + sm->Length);
|
||||
Array::Copy(si, 0, send, 0, si->Length);
|
||||
Array::Copy(sp, 0, send, si->Length, sp->Length);
|
||||
Array::Copy(sm, 0, send, si->Length + sp->Length, sm->Length);
|
||||
|
||||
return send;
|
||||
}
|
||||
};
|
||||
}
|
@ -5,8 +5,6 @@ VisualStudioVersion = 17.12.35527.113
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DroneClientCpp", "DroneClientCpp.vcxproj", "{690C304C-A70B-4B0F-BF61-8C51290BF444}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestClientConnection", "..\TestClientConnection\TestClientConnection.vcxproj", "{B7CC5245-B628-40E9-A9A0-A904E2BF25EA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@ -23,14 +21,6 @@ Global
|
||||
{690C304C-A70B-4B0F-BF61-8C51290BF444}.Release|x64.Build.0 = Release|x64
|
||||
{690C304C-A70B-4B0F-BF61-8C51290BF444}.Release|x86.ActiveCfg = Release|Win32
|
||||
{690C304C-A70B-4B0F-BF61-8C51290BF444}.Release|x86.Build.0 = Release|Win32
|
||||
{B7CC5245-B628-40E9-A9A0-A904E2BF25EA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B7CC5245-B628-40E9-A9A0-A904E2BF25EA}.Debug|x64.Build.0 = Debug|x64
|
||||
{B7CC5245-B628-40E9-A9A0-A904E2BF25EA}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B7CC5245-B628-40E9-A9A0-A904E2BF25EA}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B7CC5245-B628-40E9-A9A0-A904E2BF25EA}.Release|x64.ActiveCfg = Release|x64
|
||||
{B7CC5245-B628-40E9-A9A0-A904E2BF25EA}.Release|x64.Build.0 = Release|x64
|
||||
{B7CC5245-B628-40E9-A9A0-A904E2BF25EA}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B7CC5245-B628-40E9-A9A0-A904E2BF25EA}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -121,7 +121,8 @@
|
||||
<ClCompile Include="FormMain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DroneClient.h" />
|
||||
<ClInclude Include="Drone.h" />
|
||||
<ClInclude Include="DroneData.h" />
|
||||
<ClInclude Include="FormMain.h">
|
||||
<FileType>CppForm</FileType>
|
||||
</ClInclude>
|
||||
|
@ -26,7 +26,10 @@
|
||||
<ClInclude Include="NetClient.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DroneClient.h">
|
||||
<ClInclude Include="DroneData.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Drone.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
4
DroneClientCpp/DroneClientCpp.vcxproj.user
Normal file
4
DroneClientCpp/DroneClientCpp.vcxproj.user
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<ProjectOutputs>
|
||||
<ProjectOutput>
|
||||
<FullPath>C:\Projects\Simulator\DroneClientCpp\x64\Debug\DroneClientCpp.exe</FullPath>
|
||||
</ProjectOutput>
|
||||
</ProjectOutputs>
|
||||
<ContentFiles />
|
||||
<SatelliteDlls />
|
||||
<NonRecipeFileRefs />
|
||||
</Project>
|
@ -0,0 +1,3 @@
|
||||
FormMain.cpp
|
||||
FormMain.obj : обнаружен модуль MSIL; для MSIL последовательная компоновка отключена; выполняется полная компоновка
|
||||
DroneClientCpp.vcxproj -> C:\Projects\Simulator\DroneClientCpp\x64\Debug\DroneClientCpp.exe
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
C:\Projects\Simulator\DroneClientCpp\FormMain.cpp;C:\Projects\Simulator\DroneClientCpp\DroneClientCpp\x64\Debug\FormMain.obj
|
||||
C:\Projects\Simulator\DroneClientCpp\DroneClientCpp\x64\Debug\.NETFramework,Version=v4.7.2.AssemblyAttributes.cpp;C:\Projects\Simulator\DroneClientCpp\DroneClientCpp\x64\Debug\.NETFramework,Version=v4.7.2.AssemblyAttributes.obj
|
@ -0,0 +1,2 @@
|
||||
PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.42.34433:TargetPlatformVersion=10.0.22621.0:TargetFrameworkVersion=v4.7.2::EnableManagedIncrementalBuild=true:
|
||||
Debug|x64|C:\Projects\Simulator\DroneClientCpp\|
|
@ -0,0 +1,4 @@
|
||||
^C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\FORMMAIN.RESX
|
||||
C:\Projects\Simulator\DroneClientCpp\DroneClientCpp.vcxproj
|
||||
^C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\FORMMAIN.RESX
|
||||
C:\Projects\Simulator\DroneClientCpp\DroneClientCpp.vcxproj
|
@ -0,0 +1,4 @@
|
||||
^C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\FORMMAIN.RESX
|
||||
C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\DRONECLIENTCPP.VCXPROJ
|
||||
^C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\FORMMAIN.RESX
|
||||
C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\DRONECLIENTCPP.VCXPROJ
|
@ -0,0 +1,4 @@
|
||||
^C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\FORMMAIN.RESX
|
||||
C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\X64\DEBUG\DRONECLIENTCPP.EXE
|
||||
^C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\FORMMAIN.RESX
|
||||
C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\X64\DEBUG\DRONECLIENTCPP.EXE
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
||||
^C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\DRONECLIENTCPP\X64\DEBUG\.NETFRAMEWORK,VERSION=V4.7.2.ASSEMBLYATTRIBUTES.OBJ|C:\PROJECTS\SIMULATOR\DRONECLIENTCPP\DRONECLIENTCPP\X64\DEBUG\FORMMAIN.OBJ
|
Binary file not shown.
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,3 @@
|
||||
C:\Projects\Simulator\DroneClientCpp\DroneClientCpp\x64\Debug\DroneClientCpp.vcxproj.AssemblyReference.cache
|
||||
C:\Projects\Simulator\DroneClientCpp\DroneClientCpp\x64\Debug\DroneClientCpp.FormMain.resources
|
||||
C:\Projects\Simulator\DroneClientCpp\DroneClientCpp\x64\Debug\DroneClientCpp.vcxproj.GenerateResource.cache
|
Binary file not shown.
BIN
DroneClientCpp/DroneClientCpp/x64/Debug/FormMain.obj
Normal file
BIN
DroneClientCpp/DroneClientCpp/x64/Debug/FormMain.obj
Normal file
Binary file not shown.
BIN
DroneClientCpp/DroneClientCpp/x64/Debug/vc143.pdb
Normal file
BIN
DroneClientCpp/DroneClientCpp/x64/Debug/vc143.pdb
Normal file
Binary file not shown.
77
DroneClientCpp/DroneData.h
Normal file
77
DroneClientCpp/DroneData.h
Normal file
@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <vcclr.h>
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
|
||||
namespace DroneData {
|
||||
|
||||
public enum class DataMode : unsigned short
|
||||
{
|
||||
None = 0, Response = 1, Request = 2
|
||||
};
|
||||
|
||||
public enum class DataType : unsigned short
|
||||
{
|
||||
None = 0, Head = 1,
|
||||
DataIMU = 1001, DataPos = 1002,
|
||||
DataMotor4 = 2001, DataMotor6 = 2002
|
||||
};
|
||||
|
||||
public value struct DataHead
|
||||
{
|
||||
public:
|
||||
int Size;
|
||||
DataMode Mode;
|
||||
DataType Type;
|
||||
|
||||
static const int StrLen = sizeof(DataHead);
|
||||
};
|
||||
|
||||
public value struct XYZ
|
||||
{
|
||||
public:
|
||||
float X, Y, Z;
|
||||
};
|
||||
|
||||
public value struct DataIMU
|
||||
{
|
||||
public:
|
||||
DataHead Head;
|
||||
XYZ Acc, Gyr, Mag;
|
||||
|
||||
static const int StrLen = sizeof(DataIMU);
|
||||
};
|
||||
|
||||
public value struct DataPos
|
||||
{
|
||||
public:
|
||||
DataHead Head;
|
||||
XYZ Local;
|
||||
float LiDAR;
|
||||
|
||||
static const int StrLen = sizeof(DataPos);
|
||||
};
|
||||
|
||||
public value struct DataMotor4
|
||||
{
|
||||
public:
|
||||
DataHead Head;
|
||||
unsigned long long Count;
|
||||
float UL, UR, DL, DR;
|
||||
|
||||
static const int StrLen = sizeof(DataMotor4);
|
||||
};
|
||||
|
||||
public value struct DataMotor6
|
||||
{
|
||||
public:
|
||||
DataHead Head;
|
||||
unsigned long long Count;
|
||||
float UL, UR, LL, RR, DL, DR;
|
||||
|
||||
static const int StrLen = sizeof(DataMotor6);
|
||||
};
|
||||
}
|
Binary file not shown.
@ -1,5 +1,4 @@
|
||||
// NetClient.h
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <vcclr.h>
|
||||
@ -10,247 +9,140 @@
|
||||
using namespace System;
|
||||
using namespace System::Net;
|
||||
using namespace System::Net::Sockets;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
|
||||
namespace DroneSimulator
|
||||
{
|
||||
namespace DroneSimulator {
|
||||
|
||||
public ref class NetClient
|
||||
{
|
||||
public:
|
||||
// Вложенный класс для данных подключения
|
||||
ref class ConnectData
|
||||
{
|
||||
public:
|
||||
property bool Connect;
|
||||
property Socket^ Server;
|
||||
bool Connect;
|
||||
Socket^ Server;
|
||||
|
||||
// Добавлен конструктор
|
||||
ConnectData(bool connect, Socket^ server)
|
||||
{
|
||||
Connect = connect;
|
||||
Server = server;
|
||||
}
|
||||
};
|
||||
|
||||
// Вложенный класс для данных приема
|
||||
ref class ReceiveData
|
||||
{
|
||||
public:
|
||||
property array<Byte>^ Buffer;
|
||||
property int Size;
|
||||
property Socket^ Server;
|
||||
array<Byte>^ Buffer;
|
||||
int Size;
|
||||
Socket^ Server;
|
||||
|
||||
// Добавлен конструктор
|
||||
ReceiveData(array<Byte>^ buffer, int size, Socket^ server)
|
||||
{
|
||||
Buffer = buffer;
|
||||
Size = size;
|
||||
Server = server;
|
||||
}
|
||||
};
|
||||
|
||||
// Состояния клиента
|
||||
enum class ClientState { Error, Connected, Stop };
|
||||
|
||||
// Делегат для callback-функций
|
||||
delegate void ClientCallback(Object^ o);
|
||||
|
||||
NetClient()
|
||||
{
|
||||
Connected = false;
|
||||
ServerSocket = nullptr;
|
||||
DataServer = gcnew ServerData();
|
||||
}
|
||||
|
||||
~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)
|
||||
{
|
||||
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;
|
||||
literal int size = 1024;
|
||||
array<Byte>^ buffer = gcnew array<Byte>(size);
|
||||
};
|
||||
|
||||
bool Connected;
|
||||
Socket^ ServerSocket;
|
||||
ServerData^ DataServer;
|
||||
bool Connected = false;
|
||||
Socket^ ServerSocket = nullptr;
|
||||
ServerData^ DataServer = gcnew ServerData();
|
||||
|
||||
public:
|
||||
delegate void ClientCallback(Object^ o);
|
||||
private:
|
||||
ClientCallback^ ConnectionCallback;
|
||||
ClientCallback^ ReceiveCallback;
|
||||
|
||||
void Disconnect()
|
||||
public:
|
||||
enum class ClientState { Error, Connected, Stop };
|
||||
|
||||
ClientState Connect(String^ Addr, int Port, ClientCallback^ Connection, ClientCallback^ Receive)
|
||||
{
|
||||
if (ServerSocket != nullptr)
|
||||
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();
|
||||
ServerSocket = nullptr;
|
||||
}
|
||||
Connected = false;
|
||||
}
|
||||
|
||||
void Send(array<Byte>^ data)
|
||||
{
|
||||
if (ServerSocket != nullptr && Connected)
|
||||
{
|
||||
try { ServerSocket->Send(data); }
|
||||
catch (...) {}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void ReadCallback(IAsyncResult^ ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Проверка на null входного параметра
|
||||
if (ar == nullptr) return;
|
||||
|
||||
// Безопасное приведение типа
|
||||
ReceiveData^ cd = dynamic_cast<ReceiveData^>(ar->AsyncState);
|
||||
if (cd == nullptr || ServerSocket == nullptr || !ServerSocket->Connected)
|
||||
{
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
ReceiveData^ cd = (ReceiveData^)ar->AsyncState;
|
||||
if (cd == nullptr) 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;
|
||||
}
|
||||
try { bytes = ServerSocket->EndReceive(ar); }
|
||||
catch (...) {}
|
||||
|
||||
// Проверка на разрыв соединения
|
||||
if (bytes == 0)
|
||||
{
|
||||
Disconnect();
|
||||
ServerSocket->Close();
|
||||
Connected = false;
|
||||
|
||||
if (ConnectionCallback != nullptr)
|
||||
if (ServerSocket != nullptr)
|
||||
{
|
||||
ConnectData^ disconnectData = gcnew ConnectData();
|
||||
disconnectData->Connect = false;
|
||||
disconnectData->Server = nullptr;
|
||||
ConnectionCallback(disconnectData);
|
||||
// Исправленный вызов с конструктором
|
||||
ConnectionCallback(gcnew ConnectData(false, nullptr));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Вызов callback получения данных
|
||||
if (ReceiveCallback != nullptr && cd->Buffer != nullptr)
|
||||
{
|
||||
try
|
||||
{
|
||||
ReceiveCallback(cd);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
System::Diagnostics::Debug::WriteLine(
|
||||
"ReceiveCallback error: " + ex->Message);
|
||||
}
|
||||
}
|
||||
// Исправленный вызов с конструктором
|
||||
ReceiveCallback(gcnew ReceiveData(cd->Buffer, bytes, ServerSocket));
|
||||
|
||||
// Продолжаем прием данных
|
||||
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();
|
||||
}
|
||||
try { ServerSocket->BeginReceive(cd->Buffer, 0, ServerData::size, SocketFlags::None, gcnew AsyncCallback(this, &NetClient::ReadCallback), cd); }
|
||||
catch (...) {}
|
||||
}
|
||||
};
|
||||
}
|
BIN
DroneClientCpp/x64/Debug/DroneClientCpp.exe
Normal file
BIN
DroneClientCpp/x64/Debug/DroneClientCpp.exe
Normal file
Binary file not shown.
140
DroneClientCpp/x64/Debug/DroneClientCpp.exe.metagen
Normal file
140
DroneClientCpp/x64/Debug/DroneClientCpp.exe.metagen
Normal file
@ -0,0 +1,140 @@
|
||||
DroneClientCpp.FormMain.resources - Embedded, ContainedInManifestFile,
|
||||
ImageRuntimeVersion: v4.0.30319
|
||||
Assembly DroneClientCpp, Version=0.0.*, Culture=Инвариантный язык (Инвариантная страна):
|
||||
hash=SHA1, flags=PublicKey
|
||||
Assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:
|
||||
hash=None, flags=None
|
||||
Assembly System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:
|
||||
hash=None, flags=None
|
||||
Assembly System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:
|
||||
hash=None, flags=None
|
||||
Assembly System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a:
|
||||
hash=None, flags=None
|
||||
Assembly System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:
|
||||
hash=None, flags=None
|
||||
Assembly System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:
|
||||
hash=None, flags=None
|
||||
Assembly System.Net, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a:
|
||||
hash=None, flags=None
|
||||
Struct DroneData.DataHead: AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit
|
||||
:System.ValueType
|
||||
Fields:
|
||||
Int32 Size : Public
|
||||
DroneData.DataMode Mode : Public
|
||||
DroneData.DataType Type : Public
|
||||
Int32 StrLen IsConst : Public, Static
|
||||
Struct DroneData.XYZ: AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit
|
||||
:System.ValueType
|
||||
Fields:
|
||||
Single X : Public
|
||||
Single Y : Public
|
||||
Single Z : Public
|
||||
Struct DroneData.DataIMU: AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit
|
||||
:System.ValueType
|
||||
Fields:
|
||||
DroneData.DataHead Head : Public
|
||||
DroneData.XYZ Acc : Public
|
||||
DroneData.XYZ Gyr : Public
|
||||
DroneData.XYZ Mag : Public
|
||||
Int32 StrLen IsConst : Public, Static
|
||||
Struct DroneData.DataPos: AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit
|
||||
:System.ValueType
|
||||
Fields:
|
||||
DroneData.DataHead Head : Public
|
||||
DroneData.XYZ Local : Public
|
||||
Single LiDAR : Public
|
||||
Int32 StrLen IsConst : Public, Static
|
||||
Struct DroneData.DataMotor4: AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit
|
||||
:System.ValueType
|
||||
Fields:
|
||||
DroneData.DataHead Head : Public
|
||||
UInt64 Count : Public
|
||||
Single UL : Public
|
||||
Single UR : Public
|
||||
Single DL : Public
|
||||
Single DR : Public
|
||||
Int32 StrLen IsConst : Public, Static
|
||||
Struct DroneData.DataMotor6: AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit
|
||||
:System.ValueType
|
||||
Fields:
|
||||
DroneData.DataHead Head : Public
|
||||
UInt64 Count : Public
|
||||
Single UL : Public
|
||||
Single UR : Public
|
||||
Single LL : Public
|
||||
Single RR : Public
|
||||
Single DL : Public
|
||||
Single DR : Public
|
||||
Int32 StrLen IsConst : Public, Static
|
||||
Class DroneClient.Drone: AutoLayout, AnsiClass, Class, Public, BeforeFieldInit
|
||||
Void .ctor(): PrivateScope, Public, HideBySig, SpecialName, RTSpecialName
|
||||
Fields:
|
||||
Single AccX : Public
|
||||
Single AccY : Public
|
||||
Single AccZ : Public
|
||||
Single GyrX : Public
|
||||
Single GyrY : Public
|
||||
Single GyrZ : Public
|
||||
Single PosX : Public
|
||||
Single PosY : Public
|
||||
Single LaserRange : Public
|
||||
Single MotorUL : Public
|
||||
Single MotorUR : Public
|
||||
Single MotorDL : Public
|
||||
Single MotorDR : Public
|
||||
Methods:
|
||||
GetBytes(Object): PrivateScope, Public, Static, HideBySig
|
||||
FromBytes(Byte[], Type): PrivateScope, Public, Static, HideBySig
|
||||
DataStream(Byte[], Int32): PrivateScope, Public, HideBySig
|
||||
SendRequest(): PrivateScope, Public, HideBySig
|
||||
Class DroneSimulator.NetClient: AutoLayout, AnsiClass, Class, Public, BeforeFieldInit
|
||||
Void .ctor(): PrivateScope, Public, HideBySig, SpecialName, RTSpecialName
|
||||
Methods:
|
||||
Connect(String, Int32, ClientCallback, ClientCallback): PrivateScope, Public, HideBySig
|
||||
Close(): PrivateScope, Public, HideBySig
|
||||
Send(Byte[]): PrivateScope, Public, HideBySig
|
||||
Class DroneSimulator.NetClient+ConnectData: AutoLayout, AnsiClass, Class, NestedPublic, BeforeFieldInit
|
||||
Void .ctor(Boolean, System.Net.Sockets.Socket): PrivateScope, Public, HideBySig, SpecialName, RTSpecialName
|
||||
Fields:
|
||||
Boolean Connect : Public
|
||||
System.Net.Sockets.Socket Server : Public
|
||||
Class DroneSimulator.NetClient+ReceiveData: AutoLayout, AnsiClass, Class, NestedPublic, BeforeFieldInit
|
||||
Void .ctor(Byte[], Int32, System.Net.Sockets.Socket): PrivateScope, Public, HideBySig, SpecialName, RTSpecialName
|
||||
Fields:
|
||||
Byte[] Buffer : Public
|
||||
Int32 Size : Public
|
||||
System.Net.Sockets.Socket Server : Public
|
||||
Class DroneSimulator.NetClient+ClientCallback: AutoLayout, AnsiClass, Class, NestedPublic, Sealed, BeforeFieldInit
|
||||
:System.MulticastDelegate
|
||||
Void .ctor(System.Object, IntPtr): PrivateScope, Public, SpecialName, RTSpecialName
|
||||
Methods:
|
||||
Invoke(Object): PrivateScope, Public, Final, Virtual, VtableLayoutMask
|
||||
BeginInvoke(Object, AsyncCallback, Object): PrivateScope, Public, Final, Virtual, VtableLayoutMask
|
||||
EndInvoke(IAsyncResult): PrivateScope, Public, Final, Virtual, VtableLayoutMask
|
||||
Struct DroneSimulator.NetClient+ClientState: AutoLayout, AnsiClass, Class, NestedPublic, Sealed, BeforeFieldInit
|
||||
:System.Enum
|
||||
Fields:
|
||||
Int32 value__ : Public, SpecialName, RTSpecialName
|
||||
ClientState Error = 0 : Public, Static, Literal, HasDefault
|
||||
ClientState Connected = 1 : Public, Static, Literal, HasDefault
|
||||
ClientState Stop = 2 : Public, Static, Literal, HasDefault
|
||||
Class DroneClientCpp.FormMain: AutoLayout, AnsiClass, Class, Public, BeforeFieldInit
|
||||
:System.Windows.Forms.Form
|
||||
Void .ctor(): PrivateScope, Public, HideBySig, SpecialName, RTSpecialName
|
||||
Struct DroneData.DataMode: AutoLayout, AnsiClass, Class, Public, Sealed, BeforeFieldInit
|
||||
:System.Enum
|
||||
Fields:
|
||||
UInt16 value__ : Public, SpecialName, RTSpecialName
|
||||
DroneData.DataMode None = 0 : Public, Static, Literal, HasDefault
|
||||
DroneData.DataMode Response = 1 : Public, Static, Literal, HasDefault
|
||||
DroneData.DataMode Request = 2 : Public, Static, Literal, HasDefault
|
||||
Struct DroneData.DataType: AutoLayout, AnsiClass, Class, Public, Sealed, BeforeFieldInit
|
||||
:System.Enum
|
||||
Fields:
|
||||
UInt16 value__ : Public, SpecialName, RTSpecialName
|
||||
DroneData.DataType None = 0 : Public, Static, Literal, HasDefault
|
||||
DroneData.DataType Head = 1 : Public, Static, Literal, HasDefault
|
||||
DroneData.DataType DataIMU = 1001 : Public, Static, Literal, HasDefault
|
||||
DroneData.DataType DataPos = 1002 : Public, Static, Literal, HasDefault
|
||||
DroneData.DataType DataMotor4 = 2001 : Public, Static, Literal, HasDefault
|
||||
DroneData.DataType DataMotor6 = 2002 : Public, Static, Literal, HasDefault
|
BIN
DroneClientCpp/x64/Debug/DroneClientCpp.pdb
Normal file
BIN
DroneClientCpp/x64/Debug/DroneClientCpp.pdb
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user