【发布时间】:2011-09-02 22:43:29
【问题描述】:
我正在使用 boost::asio::socket 实现 RTMP 协议。
在 async_accept 之后,协议需要 3 步握手。请看下面的代码:
.
.
.
void RtmpServer::StartAsyncAccept()
{
// Create a new connection
nextConn = RtmpConnection::Create(this, ios);
// FIXME: shall we use async or blocking accept???
acceptor.async_accept
(
nextConn->GetSocket(),
boost::bind
(
&RtmpServer::HandleAsyncAccept,
this,
boost::asio::placeholders::error
)
);
}
.
.
.
void RtmpServer::HandleAsyncAccept(const boost::system::error_code& ec)
{
if (!ec)
{
if (nextConn->StartHandshake())
{
// Push the current connection to the queue
AddConnection(nextConn);
boost::array<char, 0> dummyBuffer;
nextConn->GetSocket().async_read_some
(
// TODO: use a strand for thread-safety.
boost::asio::buffer(dummyBuffer), // FIXME: Why boost::asio::null_buffers() not working?
boost::bind
(
&RtmpConnection::HandleData,
nextConn,
boost::asio::placeholders::error
)
);
}
}
// Start to accept the next connection
StartAsyncAccept();
}
如果握手成功,RtmpConnection::StartHandshake 将返回 true(然后将调用 RtmpConnection::HandleData),否则返回 false(连接中止,尚未处理)。
握手有 3 个主要步骤,每个步骤都涉及 Cx 和 Sx 消息,即C{0,1,2}、S{0,1,2}。
基本握手必须遵循:
// HANDSHAKE PROTOCOL
// Handshake Sequence:
// The handshake begins with the client sending the C0 and C1 chunks.
//
// The client MUST wait until S1 has been received before sending C2.
// The client MUST wait until S2 has been received before sending any
// other data.
//
// The server MUST wait until C0 has been received before sending S0 and
// S1, and MAY wait until after C1 as well. The server MUST wait until
// C1 has been received before sending S2. The server MUST wait until C2
// has been received before sending any other data.
您可能已经注意到,(像往常一样)握手需要等待。例如,
在发送 S0 之前,服务器必须等待收到 util C0。在我们的例子中,C0 只包含一个一字节的版本整数,服务器必须验证版本是否有效,然后将 S0 发送给客户端。
依此类推,与 C1/S1、C2/S2 类似(但略有不同)。
我的问题是,我应该对这次握手使用阻塞读/写还是异步?
目前我使用的是阻塞读/写,更容易实现。
但是,我搜索了很多,发现很多人建议异步读/写,因为它们具有更好的性能和更大的灵活性。
我在问我是否要使用异步套接字读/写来实现它,我该怎么办?我应该为这 3 个主要步骤创建一堆处理程序吗?或任何其他更好的建议。
示例伪代码将不胜感激。
【问题讨论】:
标签: c++ sockets boost asynchronous boost-asio