これが私が取り組んでいる単純なエコーサーバーです。サーバーはクライアントからの要求を受け入れ、クライアントが送信したものを返します。プログラムは で正常に動作しますがsocat、自分のクライアントを使用するとフリーズします。
私の古いコードの問題は、read代わりにread_some. read特定のバイト数を読み取るか、壊れたパイプ例外が発生するまでパイプをブロックしますがread_some、一度にチャンクを読み取ります。更新されたバージョンはread_some、入力ストリームを読み取り、プログラムが読み取った最後の文字が であるかどうかを確認するために\0使用し\0ます。これは、文字列リテラルのみを渡し、パイプにバイナリ データがないため機能します。
サーバーのコードは
using namespace std;
const char* epStr = "/tmp/socketDemo";
int main() {
namespace local = boost::asio::local;
boost::asio::io_service io_service;
::unlink(epStr);
local::stream_protocol::endpoint ep(epStr);
local::stream_protocol::acceptor acceptor(io_service, ep);
while(1) {
local::stream_protocol::socket *socket = new local::stream_protocol::socket(io_service);
acceptor.accept(*socket);
char buf[2048] = {0};
boost::system::error_code error;
size_t len = 0;
while(1) {
len += socket->read_some(boost::asio::buffer(buf + len, 2048 - len));
cout << "read " << len << endl;
if (buf[len] == '\0') {
break;
}
}
cout << "read " << len << " bytes" << endl;
cout << buf << endl;
boost::asio::write(*socket, boost::asio::buffer(buf, len), boost::asio::transfer_all());
}
}
socatたとえば、コマンドを使用してサーバーをテストする場合
echo "12345" | socat - UNIX-CONNECT:/tmp/socketDemo
目的の結果が返されます。
私のクライアントコードは
const char* epStr = "/tmp/socketDemo";
int main(int argc, const char* argv[]) {
boost::asio::io_service io_service;
boost::asio::local::stream_protocol::endpoint ep(epStr);
boost::asio::local::stream_protocol::socket socket(io_service);
socket.connect(ep);
boost::asio::write(socket, boost::asio::buffer(argv[1], strlen(argv[1])), boost::asio::transfer_all());
char buf[1024] = {0};
size_t len = 0;
while(1) {
len += socket.read_some(boost::asio::buffer(buf + len, 2048 - len));
std::cout << "read " << len << std::endl;
if (buf[len] == '\0') {
break;
}
}
std::cout << "read " << len << " bytes\n";
std::cout << buf << std::endl;
socket.close();
クライアントを実行すると、最初はどちらも出力がありません。クライアントを強制終了した後、サーバーは n バイトを読み取り、壊れたパイプ例外を取得することを出力します。
readこれはサーバーの機能が原因でしょうか? もしそうなら、各メッセージの最初にデータチャンクのサイズを送信せずに、どれだけのデータを読み取る必要があるかを知らせる方法はありますか? また、なぜsocatこのサーバーで問題なく動作できるのだろうかと思っています。ありがとう!