我有一台运行非常繁重的3D模拟的服务器,我希望在客户端计算机上实时显示。现在我在localhost中运行我的测试以摆脱网络品牌宽度和延迟问题,我使用boost :: asio通过网络传输我的数据(几何)。 我必须使用tcp,因为我必须压缩我的几何体,将其拆分为多个包然后通过网络发送,并在客户端上收集包以重建我的存档,因此网络包必须以良好的顺序到达。
这非常有效,我可以运行我的模拟并以~90-120fps流式传输数据,具体取决于要传输的数据量,这非常好。
我的问题是,有时候,套接字在客户端上连接()时突然需要大约1秒,因此服务器接受()的时间也很长。这导致我的模拟停止随机流式传输,我找不到问题。
我虽然问题可能来自套接字上的某种缓冲区溢出,但是只要客户端没有读取某些内容就阻止服务器写入更多数据,但它不能那样,因为我没有延迟在客户端和服务器之间,所以客户端足够快地读取包(基本上它们到达时)
以下是服务器的缩短代码:
while (1)
{
//archive some data in a stringstream using boost::archive...
boost::asio::io_service ioservice;
tcp::acceptor acceptor(ioservice, tcp::endpoint(tcp::v4(), PORT));
boost::system::error_code ignored_error;
tcp::socket socket(ioservice);
acceptor.accept(socket);
gettimeofday(&m_tv, NULL);
accept += (m_tv.tv_usec - m_timer);
m_timer = m_tv.tv_usec;
size_t bytes_sent = boost::asio::write(socket, boost::asio::buffer(ss.str()), boost::asio::transfer_all(), ignored_error);
}
在客户端我得到类似的东西:
while (1)
{
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(IP, PORT);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket.close();
socket.connect(*endpoint_iterator++, error);
}
if (error)
throw boost::system::system_error(error);
while(1)
{
boost::array<char, 200000> buf;
ss.write(buf.data(), bytes_received);
boost::system::error_code error;
bytes_received = socket.read_some(boost::asio::buffer(buf), error);
if (error == boost::asio::error::eof)
break;
else if (error)
throw boost::system::system_error(error);
}
}
我每帧都创建一个套接字,这可能是个问题,但我找不到一种更简单的方法来告诉我的客户他已经读完了包。通过每帧关闭套接字,我将eof发送给客户端,然后客户端知道他可以使用检索到的数据构建存档。
我是否可以做些什么来避免每帧打开一个套接字,而不必检查我的包的内容以了解要检索的数据的大小?