Modified
This commit is contained in:
parent
abeb88b481
commit
e9b667da26
@ -15,6 +15,7 @@ using std::queue;
|
|||||||
|
|
||||||
namespace Net {
|
namespace Net {
|
||||||
|
|
||||||
|
// the structure to store the option part of a message
|
||||||
class Option {
|
class Option {
|
||||||
public:
|
public:
|
||||||
Option(const string &key, const string &value);
|
Option(const string &key, const string &value);
|
||||||
@ -34,6 +35,7 @@ public:
|
|||||||
void updateValue(const string &value);
|
void updateValue(const string &value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// the key is unique within a message
|
||||||
shared_ptr<string> key;
|
shared_ptr<string> key;
|
||||||
shared_ptr<string> value;
|
shared_ptr<string> value;
|
||||||
};
|
};
|
||||||
@ -105,30 +107,45 @@ private:
|
|||||||
|
|
||||||
ssize_t decode_tail(const vector<char> &raw_Data, size_t offset, Message &msg);
|
ssize_t decode_tail(const vector<char> &raw_Data, size_t offset, Message &msg);
|
||||||
|
|
||||||
|
void calculate_options_hash(const vector<char> &raw_data, int32_t end_index, int16_t &sum_hash);
|
||||||
|
|
||||||
SHA256Generator sign_gen;
|
SHA256Generator sign_gen;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MessageParser {
|
class MessageParser {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// send a received buffer to parse
|
||||||
void parse(const void *buf, size_t size);
|
void parse(const void *buf, size_t size);
|
||||||
|
|
||||||
|
// Get a parsed message from the queue
|
||||||
shared_ptr<Message> getMessage();
|
shared_ptr<Message> getMessage();
|
||||||
|
|
||||||
|
// Get the count of the parsed meaasge
|
||||||
size_t getMessageCount();
|
size_t getMessageCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
// state recorder of a special part of a message
|
||||||
int head_state = -5;
|
int head_state = -5;
|
||||||
int option_state = -4;
|
int option_state = -4;
|
||||||
ssize_t body_state = -1;
|
ssize_t body_state = -1;
|
||||||
int tail_state = -4;
|
int tail_state = -4;
|
||||||
|
|
||||||
|
// factory used to read data and form the message step by step
|
||||||
MessageFactory factory;
|
MessageFactory factory;
|
||||||
|
|
||||||
|
// store the message parsed
|
||||||
queue<shared_ptr<Message>> msgs;
|
queue<shared_ptr<Message>> msgs;
|
||||||
|
// buffer to store the data give by
|
||||||
queue<char> buffer;
|
queue<char> buffer;
|
||||||
|
// buffer to temporarily store the data of the certain part related to the state of the parser
|
||||||
vector<char> temp_buffer;
|
vector<char> temp_buffer;
|
||||||
|
|
||||||
|
// temporarily record the message concentrated
|
||||||
shared_ptr<Message> temp_msg;
|
shared_ptr<Message> temp_msg;
|
||||||
|
|
||||||
|
// reset all state and refresh the parser
|
||||||
void reset_state();
|
void reset_state();
|
||||||
|
|
||||||
void locate_head();
|
void locate_head();
|
||||||
|
BIN
src/communicate/.message_parser.cpp.swo
Normal file
BIN
src/communicate/.message_parser.cpp.swo
Normal file
Binary file not shown.
@ -2,6 +2,7 @@
|
|||||||
#include "communicate/message.h"
|
#include "communicate/message.h"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
namespace Net {
|
namespace Net {
|
||||||
|
|
||||||
@ -24,18 +25,21 @@ void MessageFactory::encode_head(const Message &msg, vector<char> &raw_data) {
|
|||||||
|
|
||||||
raw_data.push_back(' ');
|
raw_data.push_back(' ');
|
||||||
|
|
||||||
|
// 协议版本
|
||||||
const string s_version = std::to_string(msg.version);
|
const string s_version = std::to_string(msg.version);
|
||||||
|
|
||||||
raw_data.insert(raw_data.end(), s_version.cbegin(), s_version.cend());
|
raw_data.insert(raw_data.end(), s_version.cbegin(), s_version.cend());
|
||||||
|
|
||||||
raw_data.push_back(' ');
|
raw_data.push_back(' ');
|
||||||
|
|
||||||
|
// 消息类型
|
||||||
const string s_type = std::to_string(msg.type);
|
const string s_type = std::to_string(msg.type);
|
||||||
|
|
||||||
raw_data.insert(raw_data.end(), s_type.cbegin(), s_type.cend());
|
raw_data.insert(raw_data.end(), s_type.cbegin(), s_type.cend());
|
||||||
|
|
||||||
raw_data.push_back(' ');
|
raw_data.push_back(' ');
|
||||||
|
|
||||||
|
// 会话ID
|
||||||
const string s_tid = std::to_string(msg.tid);
|
const string s_tid = std::to_string(msg.tid);
|
||||||
|
|
||||||
raw_data.insert(raw_data.end(), s_tid.cbegin(), s_tid.cend());
|
raw_data.insert(raw_data.end(), s_tid.cbegin(), s_tid.cend());
|
||||||
@ -67,6 +71,16 @@ void MessageFactory::encode_options(const Message &msg,
|
|||||||
raw_data.push_back('\n');
|
raw_data.push_back('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 计算头部和配置部分的哈希值
|
||||||
|
int16_t sum_hash;
|
||||||
|
|
||||||
|
calculate_options_hash(raw_data, raw_data.size() - 1, sum_hash);
|
||||||
|
const string sum_hash_str = std::to_string(sum_hash);
|
||||||
|
raw_data.insert(raw_data.end(), sum_hash_str.cbegin(), sum_hash_str.cend());
|
||||||
|
|
||||||
|
raw_data.push_back('\r');
|
||||||
|
raw_data.push_back('\n');
|
||||||
|
|
||||||
raw_data.push_back('\r');
|
raw_data.push_back('\r');
|
||||||
raw_data.push_back('\n');
|
raw_data.push_back('\n');
|
||||||
}
|
}
|
||||||
@ -158,8 +172,26 @@ ssize_t MessageFactory::decode_options(const vector<char> &raw_data,
|
|||||||
msg.addOption(key.c_str(), value.c_str());
|
msg.addOption(key.c_str(), value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sum_hash_range = index - 2;
|
||||||
|
|
||||||
--index;
|
--index;
|
||||||
|
|
||||||
|
string sum_hash_str;
|
||||||
|
while((c = raw_data[index++]) != '\r') {
|
||||||
|
sum_hash_str.push_back(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(raw_data[index++] != '\n') {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t sum_hash = std::stoi(sum_hash_str);
|
||||||
|
int16_t sum_hash_check;
|
||||||
|
|
||||||
|
calculate_options_hash(raw_data, sum_hash_range, sum_hash_check);
|
||||||
|
|
||||||
|
if(sum_hash_check != sum_hash) return -1;
|
||||||
|
|
||||||
if (raw_data[index++] != '\r' || raw_data[index++] != '\n')
|
if (raw_data[index++] != '\r' || raw_data[index++] != '\n')
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -200,6 +232,24 @@ ssize_t MessageFactory::decode_tail(const vector<char> &raw_data, size_t offset,
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessageFactory::calculate_options_hash(const vector<char> &raw_data, int32_t end_index, int16_t &sum_hash) {
|
||||||
|
|
||||||
|
if(end_index > raw_data.size()) {
|
||||||
|
throw std::runtime_error("end index out of range");
|
||||||
|
}
|
||||||
|
|
||||||
|
sum_hash = 0;
|
||||||
|
|
||||||
|
int32_t index = 0;
|
||||||
|
|
||||||
|
for(auto &c : raw_data) {
|
||||||
|
sum_hash += static_cast<int16_t>(c);
|
||||||
|
sum_hash %= 65535;
|
||||||
|
if (index++ >= end_index) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool MessageFactory::decodeMessage(const vector<char> &raw_data, Message &msg) {
|
bool MessageFactory::decodeMessage(const vector<char> &raw_data, Message &msg) {
|
||||||
msg.clear();
|
msg.clear();
|
||||||
|
|
||||||
@ -251,4 +301,5 @@ bool MessageFactory::decodeMessageTail(const vector<char> &raw_data, Message &ms
|
|||||||
if(!~decode_tail(raw_data, 0, msg)) return false;
|
if(!~decode_tail(raw_data, 0, msg)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Net
|
} // namespace Net
|
||||||
|
@ -6,12 +6,16 @@ namespace Net {
|
|||||||
|
|
||||||
void MessageParser::parse(const void *buf, size_t size) {
|
void MessageParser::parse(const void *buf, size_t size) {
|
||||||
|
|
||||||
|
// push all data in buff into queue named buffer
|
||||||
const char *c_buf = (const char *)buf;
|
const char *c_buf = (const char *)buf;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
buffer.push(c_buf[i]);
|
buffer.push(c_buf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process the data byte by byte until the queue is empty
|
||||||
while(!buffer.empty()) {
|
while(!buffer.empty()) {
|
||||||
|
|
||||||
|
// if there is no message concentrated then create new message
|
||||||
if (temp_msg == nullptr) {
|
if (temp_msg == nullptr) {
|
||||||
temp_msg = std::make_shared<Message>();
|
temp_msg = std::make_shared<Message>();
|
||||||
}
|
}
|
||||||
@ -26,9 +30,12 @@ void MessageParser::parse(const void *buf, size_t size) {
|
|||||||
locate_tail();
|
locate_tail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tail processing done
|
||||||
if(!tail_state){
|
if(!tail_state){
|
||||||
|
// release the message concentrated
|
||||||
msgs.push(temp_msg);
|
msgs.push(temp_msg);
|
||||||
temp_msg = nullptr;
|
temp_msg = nullptr;
|
||||||
|
// reset the state of the parser
|
||||||
reset_state();
|
reset_state();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,6 +98,8 @@ void MessageParser::locate_option() {
|
|||||||
option_state++;
|
option_state++;
|
||||||
else if(c == '\r')
|
else if(c == '\r')
|
||||||
option_state = -1;
|
option_state = -1;
|
||||||
|
else if (c > 47 && c < 58)
|
||||||
|
option_state++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(option_state == -3) {
|
if(option_state == -3) {
|
||||||
@ -219,8 +228,10 @@ void MessageParser::locate_tail() {
|
|||||||
|
|
||||||
void MessageParser::reset_state() {
|
void MessageParser::reset_state() {
|
||||||
temp_buffer.clear();
|
temp_buffer.clear();
|
||||||
|
// reset the message concentrated
|
||||||
if(temp_msg != nullptr)
|
if(temp_msg != nullptr)
|
||||||
temp_msg->clear();
|
temp_msg->clear();
|
||||||
|
// reset the state recorder
|
||||||
head_state = -5;
|
head_state = -5;
|
||||||
option_state = -4;
|
option_state = -4;
|
||||||
body_state = -1;
|
body_state = -1;
|
||||||
|
@ -26,6 +26,11 @@ TEST(Message_Test, base_test_1) {
|
|||||||
mf.encodeMessage(msg, rd);
|
mf.encodeMessage(msg, rd);
|
||||||
PrintTools::printInfoBuffer(rd, "Message Raw Data");
|
PrintTools::printInfoBuffer(rd, "Message Raw Data");
|
||||||
|
|
||||||
|
for(auto &c : rd) {
|
||||||
|
printf("%c", c);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
ASSERT_TRUE(mf.decodeMessage(rd, msg));
|
ASSERT_TRUE(mf.decodeMessage(rd, msg));
|
||||||
|
|
||||||
ASSERT_EQ(msg.getTID(), 1);
|
ASSERT_EQ(msg.getTID(), 1);
|
||||||
@ -55,8 +60,6 @@ TEST(MessageParser_Test, base_test_1) {
|
|||||||
MessageParser mp;
|
MessageParser mp;
|
||||||
mp.parse(rd.data(), rd.size());
|
mp.parse(rd.data(), rd.size());
|
||||||
|
|
||||||
printf("SIZE: %lu\n", rd.size());
|
|
||||||
|
|
||||||
ASSERT_EQ(mp.getMessageCount(), 1);
|
ASSERT_EQ(mp.getMessageCount(), 1);
|
||||||
|
|
||||||
shared_ptr<Message> p_msg = mp.getMessage();
|
shared_ptr<Message> p_msg = mp.getMessage();
|
||||||
|
Loading…
Reference in New Issue
Block a user