升压插座问题
Issue with Boost Sockets
首先,我想声明我是C++和提升的初学者,尽管我确实有一些Java和C#等语言的经验。
话虽如此,我在通过 Boost TCP 套接字传输数据时遇到了问题。我正在使用以下代码:
要发送:
tcp::socket s(io_service);
boost::asio::connect(s, iterator);
string response = static_cast<ostringstream*>( &(ostringstream() << arg1) )->str()
+ "," + static_cast<ostringstream*>( &(ostringstream() << arg2) )->str()
+ "," + static_cast<ostringstream*>( &(ostringstream() << arg3) )->str()
+ "," + static_cast<ostringstream*>( &(ostringstream() << arg4) )->str()
+ "," + static_cast<ostringstream*>( &(ostringstream() << arg5) )->str()
+ "," + static_cast<ostringstream*>( &(ostringstream() << arg6) )->str();
//pad the rest
while (response.length() < max_length)
{
response += ' ';
}
boost::asio::write(s, boost::asio::buffer(response, sizeof(response)));
阅读:
tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
while(true)
{
socket_ptr sock(new tcp::socket(io_service));
a.accept(*sock);
boost::thread t(boost::bind(session, sock));
}
...
void session(socket_ptr sock)
{
char data[max_length];
size_t length;
try
{
while(true)
{
boost::system::error_code error;
//size_t length = sock->read_some(boost::asio::buffer(data), error);
length = boost::asio::read(*sock, boost::asio::buffer(data, sizeof data));
std::cout << "Length " << length << endl;
if (error == boost::asio::error::eof)
{
break; // Connection closed cleanly by peer.
}
else if (error)
{
throw boost::system::system_error(error); // Some other error.
}
}
}
catch (std::exception& e)
{
std::cout << data << endl;
string message = e.what();
if(std::string::npos != message.find(END_OF_FILE))
{
domeSomethingWithTheData(data);
memset(data, 0, sizeof data);
}
else
{
std::cout << data <<endl;
std::cerr << "Exception in thread: " << e.what() << "n";
}
}
}
我无法理解的是,无论我使用什么(boost::asio::read
或sock->read_some
),我都不会获得超过 32 个字符的数据。我尝试将缓冲区的大小增加到2048
,但问题仍然存在。
缓冲区始终包含超过 32 个字符(其中大部分是垃圾),但我假设这些字符实际上不是从客户端发送的,而是来自服务器端缓冲区的实际分配,因为std::cout << "Length " << length
打印出 32。
任何关于我如何从客户端向服务器发送任意数量的字符的信息将不胜感激。
编辑:
在 Rafal Rawicki 提供的指针之后,我现在使用以下代码:
boost::asio::streambuf buffer;
boost::asio::read_until(*sock, buffer, 'n');
std::istream is(&buffer);
std::string line;
std::getline(is, line);
std::cout << line << std::endl;
客户端保持不变,唯一的例外是我在最后添加一个n
。但是,这会产生很多End of file
例外。
这实际上不是你问题的答案。但简短的建议。
你的字符串连接代码很残酷!
string response = static_cast<ostringstream*>( &(ostringstream() << arg1) )->str()
+ "," + static_cast<ostringstream*>( &(ostringstream() << arg2) )->str()
+ "," + static_cast<ostringstream*>( &(ostringstream() << arg3) )->str()
+ "," + static_cast<ostringstream*>( &(ostringstream() << arg4) )->str()
+ "," + static_cast<ostringstream*>( &(ostringstream() << arg5) )->str()
+ "," + static_cast<ostringstream*>( &(ostringstream() << arg6) )->str();
对于每个参数,您创建一个新ostringstream
,将值写入它,然后不必要地取消引用它,然后不必要地将其转换为它已经拥有的类型。最后,您使用字符串串联来构建最终字符串。
这种字符串连接既不高效,也不复杂(需要临时对象、一些浪费的分配等)。
ostringstream
是字符串连接和格式化的正确工具,它高效且复杂。
长话短说,您的代码应该如下所示:
ostringstream oss;
oss << arg1 << "," << arg2 << "," << arg3 << "," << arg4 << "," << arg5 << "," << arg6;
string response = oss.str();
boost::asio::read
应该读取数据,直到缓冲区已满或发生错误。
boost::asio::socket::read_some
应该从套接字读取一些数据。
要读取所需的数据量,您可以:
- 使用boost::asio::阅读,就像你尝试的那样。
- 使用这些函数的多次调用来读取越来越多的数据
- 使用
read_until
将数据读取到预期的分隔符 - 使用此
boost::asio::read
重载,它以参数completion_condition
,例如字节数。
另外,请查看与 Boost.Asio 同步操作的问题,并考虑改用异步操作。
编辑:我错过了客户端代码中不正确的缓冲区初始化。boost::asio::read
的使用是正确的。
你不能像这样初始化缓冲区:
boost::asio::buffer(response, sizeof(response));
因为sizeof
返回std::string
结构的大小,而不是整个字符串。在我的机器上,它总是 8。用:
boost::asio::buffer(response);
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- RECV插座类型参数的问题
- 升压插座问题