This commit is contained in:
Lenheart 2024-04-03 18:59:34 +08:00
parent 457c88679d
commit 9bc3e7d1b9
3 changed files with 236 additions and 38 deletions

View File

@ -73,6 +73,10 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>F:\App\VisualStudio\OtherProject\SyncWebServer\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(SolutionDir)include;H:\Visual Studio\VS_C_AND_C++_PROJECT\SyncWebServer\include\nlohmann;$(IncludePath)</IncludePath>
<ExternalIncludePath>$(SolutionDir)include;$(IncludePath)</ExternalIncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>

View File

@ -21,24 +21,6 @@ unsigned char* IntToByteLittle(int Count)
return b;
}
unsigned char* StringToByte(std::string str)
{
char* cstr = (char*)str.c_str();
int Count = strlen(cstr);
unsigned char* temp = IntToByteLittle(Count);
unsigned char* buffer = new unsigned char[Count + 4];
for (size_t i = 0; i < 4; i++)
{
buffer[i] = temp[i];
}
delete[] temp;
for (size_t z = 4; z < Count + 4; z++)
{
buffer[z] = cstr[z - 4];
}
return buffer;
}
# define skey {8,1,2,5,4}
//单个字符异或运算
@ -67,3 +49,25 @@ void Cutecode(char* pstr, int* pkey) {
for (int i = 0; i < len; i++)
*(pstr + i) = CutcodeChar(*(pstr + i), pkey[i % 5], pkey[(i + 18) % 5]);
}
unsigned char* StringToByte(std::string str)
{
char* cstr = (char*)str.c_str();
int Count = strlen(cstr);
unsigned char* temp = IntToByteLittle(Count);
unsigned char* buffer = new unsigned char[Count + 4];
for (size_t i = 0; i < 4; i++)
{
buffer[i] = temp[i];
}
delete[] temp;
int key[] = skey;
Makecode(cstr, key);
for (size_t z = 4; z < Count + 4; z++)
{
buffer[z] = cstr[z - 4];
}
return buffer;
}

230
main.cpp
View File

@ -3,6 +3,7 @@
#include <thread>
#include <mutex>
#include <queue>
#include <string>
#include "Tool.hpp"
#include "nlohmann/json.hpp"
@ -11,7 +12,14 @@ using namespace std;
using namespace asio;
using json = nlohmann::json;
# define skey {8,1,2,5,4}
io_context ioContext;
ip::udp::endpoint endpoint(ip::udp::v4(), 12345);
ip::udp::socket socketObj(ioContext, endpoint);
std::mutex mtx;
int TotalId = 0;
//信息包结构体
struct MessagePack
@ -21,6 +29,97 @@ struct MessagePack
};
std::queue<std::pair<udp::endpoint, MessagePack*>> messages;
struct ClientObject
{
udp::endpoint Client;
int HeartTime;
int ObjectId;
};
//主机
ClientObject MasterClient;
//从机MAP
std::map< udp::endpoint, ClientObject> SubClient;
//身份包
void IdentificationPack(udp::endpoint Client , json Jso) {
int Type = Jso["IC"].get<int>();
switch (Type)
{
//主机
case 0:
std::cout << "主机: " << Client.address() << " : " << Client.port() << "已连接" << endl;;
MasterClient.Client = Client;
MasterClient.HeartTime = clock();
MasterClient.ObjectId = TotalId;
TotalId++;
break;
//从机
case 1:
std::cout << "从机: " << Client.address() << " : " << Client.port() << "已连接" << endl;;
ClientObject SubBuffer;
SubBuffer.Client = Client;
SubBuffer.HeartTime = clock();
SubBuffer.ObjectId = TotalId;
TotalId++;
SubClient[Client] = SubBuffer;
break;
}
}
//心跳包
void UpdateHeartPack(udp::endpoint Client, json Jso) {
int Type = Jso["IC"].get<int>();
switch (Type)
{
//主机
case 0:
MasterClient.HeartTime = clock();
break;
//从机
case 1:
SubClient[Client].HeartTime = clock();
break;
}
std::string P = "{ \"op\" : 11 }";
unsigned char* StrPck = StringToByte(P);
socketObj.send_to(buffer(StrPck, strlen(P.c_str()) + 4), Client);
}
//下发信息包
void DistributePack(udp::endpoint Client, json Jso) {
std::string Str = Jso.dump();
unsigned char* StrPck = StringToByte(Str);
for (const auto& pair : SubClient) {
socketObj.send_to(buffer(StrPck, strlen(Str.c_str()) + 4),pair.first);
}
std::cout << "[ ";
for (size_t i = 0; i < strlen(Str.c_str()) + 4; i++)
{
std::cout << (int)(StrPck[i]);
std::cout << ",";
}
std::cout << "]" << endl;
}
//得到所有对象包
void GetAllClient(udp::endpoint Client, MessagePack* Pck) {
json Pack;
Pack["Arr"] = json::array();
for (const auto& pair : SubClient) {
std::cout << "遍历到" << std::endl;
json Jso;
Jso["ObjectId"] = pair.second.ObjectId;
Jso["Client"] = (pair.second.Client.address().to_string() + " : " + (std::to_string(pair.second.Client.port())));
Pack["Arr"].push_back(Jso);
}
std::string jsonString = Pack.dump();
unsigned char* StrPck = StringToByte(jsonString);
socketObj.send_to(buffer(StrPck, strlen(jsonString.c_str()) + 4), Client);
}
//销毁信息包
void DestoryPck(MessagePack* Pck) {
delete[] Pck->Msg;
@ -37,15 +136,65 @@ void TotalMessageLogic(udp::endpoint Client, MessagePack* Pck) {
int key[] = skey;
Cutecode(Code, key);
json j = json::parse(Code);
std::cout << j["op"] << std::endl;
try
{
json Jso = json::parse(Code);
switch (Jso["op"].get<int>())
{
//身份包
case 0:
IdentificationPack(Client, Jso);
break;
//心跳包
case 1:
UpdateHeartPack(Client, Jso);
break;
//下发信息包
case 2:
DistributePack(Client, Jso);
break;
//得到所有对象
case 3:
GetAllClient(Client, Pck);
break;
default:
break;
}
}
catch (const std::exception&)
{
std::cout << "错误!!!!!!!!!!!!!请联系管理员" << std::endl;
}
DestoryPck(Pck);
}
void CheckClientHeart(int NowTime) {
if (!MasterClient.HeartTime)return;
if ((NowTime - MasterClient.HeartTime) > 10000) {
cout << "主机已断开连接 程序结束,请重新启动服务端" << std::endl;;
Sleep(3000);
exit(0);
}
std::vector<udp::endpoint> keysToRemove;
for (const auto& pair : SubClient) {
if ((NowTime - pair.second.HeartTime) > 10000) {
cout << "从机: " << pair.first.address() << " : " << pair.first.port() << " 已失去连接." << endl;
keysToRemove.push_back(pair.first);
}
}
// 移除标记的元素
for (udp::endpoint key : keysToRemove) {
SubClient.erase(key);
}
}
//子线程消息处理逻辑
void handle_messages() {
static int BaseTime = clock();
while (true) {
std::pair<udp::endpoint, MessagePack*> message;
{
@ -57,41 +206,82 @@ void handle_messages() {
messages.pop();
}
}
int NowTime = clock();
if (NowTime - BaseTime > 3000) {
CheckClientHeart(NowTime);
BaseTime = NowTime;
}
}
}
int main() {
io_context ioContext;
ip::udp::endpoint endpoint(ip::udp::v4(), 12345);
ip::udp::socket socket(ioContext, endpoint);
int main() {
//char test[] = {33, 80, 55, 37, 36, 125, 101, 105, 126, 111, 33, 80, 122, 47, 109, 119, 125, 98, 104, 36, 57, 143, 39, 113, 36, 57, 78, 64, 63, 54, 33, 141, 39, 55, 62, 63, 52, 124, 118, 135};
//int key[] = skey;
//Cutecode(test, key);
//for (size_t i = 0; i < 40; i++)
//{
// std::cout << (int)test[i] << ",";
//}
//io_context ioContext;
//ip::udp::endpoint endpoint(ip::udp::v4(), 12345);
//ip::udp::socket socket(ioContext, endpoint);
std::thread message_thread(handle_messages);
while (true) {
char data[1024];
ip::udp::endpoint senderEndpoint;
size_t length = socket.receive_from(buffer(data), senderEndpoint);
size_t length = 0;
if (length >= 4) {
uint32_t msgLength = *(reinterpret_cast<uint32_t*>(data));
if (length >= msgLength + 4) {
unsigned char* Str = new unsigned char[msgLength];
memcpy(Str, data + 4, msgLength);
MessagePack* Pck = new MessagePack();
Pck->Msg = Str;
Pck->Length = msgLength;
try
{
length = socketObj.receive_from(buffer(data), senderEndpoint);
if (length >= 4) {
uint32_t msgLength = *(reinterpret_cast<uint32_t*>(data));
std::lock_guard<std::mutex> lock(mtx);
messages.push(std::make_pair(senderEndpoint, Pck));
if (length >= msgLength + 4) {
unsigned char* Str = new unsigned char[msgLength];
memcpy(Str, data + 4, msgLength);
MessagePack* Pck = new MessagePack();
Pck->Msg = Str;
Pck->Length = msgLength;
std::lock_guard<std::mutex> lock(mtx);
messages.push(std::make_pair(senderEndpoint, Pck));
}
else {
cout << "Incomplete message received, length: " << length << endl;
}
}
else {
cout << "Incomplete message received, length: " << length << endl;
cout << "Invalid message length received" << endl;
}
}
else {
cout << "Invalid message length received" << endl;
catch (const asio::system_error& e)
{
if (e.code() == asio::error::connection_reset) {
if (MasterClient.Client == senderEndpoint) {
cout << "主机已断开连接 程序结束,请重新启动服务端";
exit(0);
}
else if (SubClient.count(senderEndpoint)) {
cout << "从机: " << senderEndpoint.address() <<":" << senderEndpoint.port() << " 已失去连接." << endl;
SubClient.erase(senderEndpoint);
}
// 处理断开连接的逻辑
break;
}
else {
throw;
}
}
}
return 0;