我有第三方服務器,我正在爲它編寫一個dll接口,我的客戶端使用我的dll與服務器進行通信。根據數據包序列號調度響應數據包
該協議使用長tcp連接,所有流量都來自此tcp連接。有可能被髮送/同時接收多個數據包,喜歡的send_msg
和heart_beat
在同一時間,所以我必須用ASYNC_WRITE/async_read以防止阻塞操作。每個數據包都有其序列號。例如,我發送序列號爲123的消息,然後等待服務器響應序列號爲123的數據包。
UPDATE:無法保證服務器按順序響應數據包。如果以A
,B
的順序發送兩個數據包,則響應順序可以是response_B
,response_A
。序列號是識別數據包的唯一方法。
包的樣子:
4bytes size + 2 bytes crc check + 4 bytes SEQUENCE ID + ....
的問題是,我的客戶誰用我的DLL喜歡使用功能的阻斷方式,他們不喜歡的回調。比如,他們喜歡
bool DLL_EXPORT send_msg(...) {
// send msg via long_connection, the seq_id==123
// recv msg via long_connection, just want the packet with seq_id==123 (How?)
return if_msg_sent_successfully;
}
我使用升壓ASIO,我不知道是否有任何工具類boost的,或者設計模式適用於這種情況下,這裏是解決方案,我可以想出用:
// use a global std::map<seq_id, packet_content>
std::map<int, std::string> map_received;
每次接收分組時,寫入seq_id
和packet_body
到map_received和send_msg
函數看起來像
bool DLL_EXPORT send_msg(...) {
// async_send msg via long_connection, the seq_id==123
while(not_time_out) {
if(map_received.find(123) != map_received.end()) {
// get the packet and erase the 123 pair
}
Sleep(10); // prevent cpu cost
}
return if_msg_sent_successfully;
}
該解決方案很難看,因此必須有更好的設計。任何想法?
這正是我所需要的。使用std :: promise作爲返回值非常聰明。這真的有很大幫助,謝謝你們。 – aj3423
@ aj3423另外一個注意事項:因爲這隻適用於使用多線程的情況,所以您必須確保訪問'map_received'是序列化的(例如使用互斥鎖),因爲對'std :: map'的寫入訪問不是線程安全的。 –
是的我會用多線程的互斥體,感謝提示m.s. – aj3423