我正在寫一個使用Boost Asio的死亡簡單玩具鍵值存儲,並且發生了一些非常奇怪的事情。Boost Asio不完整寫入插座
基於字符串的協議是這樣的:
S <key> <value> // to set a key
G <key> // to get the key value
L // to list all key-value pairs
寫入是同步的,使用
升壓:: ASIO ::寫(socket_,升壓:: ASIO ::緩衝液( resp,len));
其中socket_是一個boost :: asio :: ip :: tcp :: socket - 與asynchrounous寫故事不會改變,顯然。
的問題是,有時它不寫入套接字所有假設寫,或輸出以某種方式錯位字節...錯位列表輸出的
實施例(在本地主機上,使用nc,echo和hexdump):
> echo S a 12 | nc localhost 5000
A
> echo S b 23 | nc localhost 5000
A
> echo L | nc localhost 5000 | hexdump -C
00000000 61 3a 20 31 32 3b 20 62 60 00 00 00 00 00 |a: 12; b`.....|
0000000e
> echo L | nc localhost 5000 | hexdump -C
00000000 61 3a 20 31 32 3b 20 62 3a 20 32 33 3b 20 |a: 12; b: 23; |
0000000e
我從Ubuntu 14.10版本庫使用Boost 1.55。 遵循服務於客戶端的函數的代碼。
非常感謝您的任何提示!
void ClientSession::handle_read(const boost::system::error_code& error, size_t bytes_transferred) {
if (!error) {
std::string cmd(data_, bytes_transferred);
cmd = trim_str(cmd);
const char* resp = NULL;
int len = 0;
switch(cmd.at(0)) {
case SET: {
std::size_t k_pos = cmd.find(" ") + 1;
std::size_t v_pos = cmd.find(" ", k_pos+1) + 1;
std::string key = trim_str(cmd.substr(k_pos, v_pos-3));
std::string value = trim_str(cmd.substr(v_pos, cmd.length()-1));
cout << "SET key " << key << ", value " << value << "*" <<endl;
kvs->db[key] = std::atoi(value.c_str());
resp = "A";
len = 1;
break;
}
case GET: {
std::size_t k_pos = cmd.find(" ") + 1;
std::string key = trim_str(cmd.substr(k_pos, cmd.length()));
cout << "GET key " << key << "*" << endl;
int value = kvs->db[key];
char str[5];
sprintf(str, "%d", value);
resp = (const char*) str;
len = strlen(resp);
break;
}
case LIST: {
ostringstream os;
for (std::map<string, int>::iterator iter = kvs->db.begin();
iter != kvs->db.end(); ++iter)
os << iter->first << ": " << iter->second << "; ";
cout << "list: " << os.str().c_str() << endl;
resp = os.str().c_str();
len = strlen(resp);
break;
}
case DEL: {
std::size_t k_pos = cmd.find(" ") + 1;
std::string key = trim_str(cmd.substr(k_pos, cmd.length()));
kvs->db.erase(key);
resp = "A";
len = 1;
break;
}
default: {
resp = "NACK.";
len = 5;
}
}
cout << "resp: " << resp << "*" << endl;
cout << "len: " << len << "*" << endl;
std::size_t written = boost::asio::write(socket_,
boost::asio::buffer(resp, len));
cout << "written: " << written << endl;
boost::system::error_code ignored_ec;
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
socket_.close();
} else
delete this;
不夠公平,謝謝! - 正如你可能已經猜到的那樣,我還沒有對那些C微妙的怪癖非常熟悉:/ –
我會說:永遠不要習慣C的怪癖!使用C++代替:http://paste.ubuntu.com/10759474/(另外,'enable_shared_from_this'而不是'delete this' code smell;使用Boost'array_source'來減少複製,boost'string_ref'消除它,但這是優化) – sehe
現在通過編譯器:[Live Live Coliru](http://coliru.stacked-crooked.com/a/3b5a928e311f3162)。 ** CAVEAT **將'KV_IOTHREADS_NUM'保留爲1,直到您執行線程安全 – sehe