Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6476557
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T06:50:22+00:00 2026-05-25T06:50:22+00:00

I’m implementing an RTMP protocol using boost::asio::socket . After the async_accept, the protocol requires

  • 0

I’m implementing an RTMP protocol using boost::asio::socket.

After the async_accept, the protocol requires a 3-step handshake. See the code below:

.
.
.
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();
}

The RtmpConnection::StartHandshake will return true if the handshake succeeded (then RtmpConnection::HandleData will be called), false otherwise (connection aborted, not handled yet).

There are 3 main steps for the handshake, each involves Cx and Sx messages, i.e., C{0,1,2}, S{0,1,2}.

The basic handshake MUST follow:

// 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.

As you may have noticed that, (as usual), a handshake requires waiting. For example,

The server MUST wait util C0 has been received before sending S0. In our case C0 only contains a one-byte version integer, and the server has to verify if the version is valid or not, then send S0 to the client.

And so on, similar as C1/S1, C2/S2 (but slightly different).

My question is, should I use blocking Read/Write for this handshake, or asynchronous?

Currently I’m using blocking Read/Write, which is easier to implement.

However, I googled a lot, finding out that a lot of guys suggest asynchronous read/write, because they have better performance and more flexibility.

I’m asking if I want to implement it using asynchronous socket read/write, what should I do? Should I create a bunch of handlers for these 3 main steps? or any other better suggestions.

Sample pseudo code will be appreciated.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T06:50:23+00:00Added an answer on May 25, 2026 at 6:50 am

    The typical two approaches are:

    1. async. operations with a small number of threads
    2. sync. operations with one thread per connection/client

    I believe it’s well established that in terms of scalability, (1) beats (2), but in terms of simplicity of the code (2) typically beats (1). If you don’t expect to handle more than a few connections ever, you might want to consider (2).

    It’s possible to use coroutines to make your asynchronous code look synchronous, and get the best of both worlds. However, there’s no platform independent way of doing it, and it might get quite messy, since there’s also no standard way to do it. I believe it’s not done very often.

    One simple way to use async. operations is to have an implicit state machine, based in which callback will be used when there is more data to read from (or write to) the socket. That would look something like this (simplified):

    class my_connection {
       tcp::socket m_sock;
       char m_buf[1024];
       int m_pos;
    
       void async_handshake(size_t bytes_transferred, error_code& ec) {
          if (ec) { ... }
          m_pos += bytes_transferred;
    
          if (m_pos == handshake_size) {
             parse_handshake();
             return;
          }
    
          m_sock.async_read(asio::buffer(m_buf + m_pos, handshake_size - m_pos), boost::bind(&async_handshake, shared_from_this(), _1, _2));
       }
    
       void parse_handshake()
       {
          // ...
          m_pos = 0;
          // ... fill m_buf with handshake ...
          async_write_handshake();
       }
    
       void async_write_handshake(size_t bytes_transferred, error_code& ec) {
          if (ec) { ... }
          m_pos += bytes_transferred;
    
          if (m_pos == handshake_size) {
             handshake_written();
             return;
          }
    
          m_sock.async_write_some(asio::buffer(m_buf + m_pos, handshake_size - m_pos), boost::bind(&async_write_handshake, shared_from_this(), _1, _2));
       }
    
       void handshake_written() { /* ... */ }
    };
    

    This may not be very sustainable once the protocol gets more complicated though. To deal with that, it might be simpler to have an explicit state machine in your connection class, and you have a single read callback, and a single write callback. Whenever some data has been written or read, you perform an action based on which state the connection is in.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti
I'm using v2.0 of ClassTextile.php, with the following call: $testimonial_text = $textile->TextileRestricted($_POST['testimonial']); ... and
I am using Paperclip to handle profile photo uploads in my app. They upload
Seemingly simple, but I cannot find anything relevant on the web. What is the
Does anyone know how can I replace this 2 symbol below from the string
this is what i have right now Drawing an RSS feed into the php,
I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
I have just tried to save a simple *.rtf file with some websites and

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.