๐Ÿ“– C๋ž‘ C++

Boost-echo tcp client & server๋ฅผ ์‚ดํŽด๋ณด์ž (1)

bell22 2021. 6. 11. 11:36

Boost๋Š” C++์„ ํ•˜๋‹ค๋ณด๋ฉด ์–ธ์  ๊ฐ„ ๋ฐ˜๋“œ์‹œ ๊ผญ ์‚ฌ์šฉํ•˜๊ฒŒ๋  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค

Boost์— ๋Œ€ํ•œ ์„ค๋ช…์€ ์•„๋ž˜์— ์ฒจ๋ถ€ํ•  Boost ๊ณต์‹ํ™ˆํŽ˜์ด์ง€์—์„œ ํ•œ๋ฒˆ ์ฝ์–ด๋ณด๋Š”๊ฑธ ์ถ”์ฒœํ•œ๋‹ค (์žฌ๋ฐŒ์Œ)

 

์ฒ˜์Œ์— boost๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š”,

STL(Standard Template Library)์ด๋ž‘ ์—ญํ• ์ด ๊ฐ™์€ ๊ฒƒ ๊ฐ™์€๋ฐ, ์™œ ์“ฐ์ง€? ํ–ˆ๋Š”๋ฐ

STL์„ ํ™œ์šฉํ•ด์„œ ๋ญ”๊ฐ€ ์ข€๋” ํ•ด์•ผํ•  ๋•Œ, boost์—๋Š” ์ด๋ฏธ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ๋งŽ์ด ์žˆ์—ˆ๋‹ค

์˜ˆ์ œ ํ™œ์šฉํ•ด์„œ ์“ฐ๋‹ค๋ณด๋ฉด ๊ธˆ๋ฐฉ ์ต์ˆ™ํ•ด์งˆ ์ˆ˜ ์žˆ๋‹น

 

์„œ๋ก ์ด ๊ธธ์—ˆ๋Š”๋ฐ,

Boost ํ™œ์šฉ์„ ์ข€ ๋” ์ž˜ํ•ด๋ณด๊ธฐ ์œ„ํ•ด์„œ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ƒ˜ํ”Œ ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ์”ฉ

๊ณต๋ถ€ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค

์‹ค์ œ ํ™œ์šฉํ•  ๋•Œ ๋†“์นœ ๋ถ€๋ถ„ ํ™•์ธ๋„ ํ• ๊ฒธใ…‹

 

Boost Asio์— ๋Œ€ํ•œ ์„ค๋ช…์€ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜๊ธธ ๋ฐ”๋ž€๋‹ค

 

์ฒซ ๋ฒˆ์งธ๋กœ ํ™•์ธํ•œ ์˜ˆ์ œ๋Š” Async TCP Server์™€ Client ๊ตฌํ˜„ ์˜ˆ์ œ์ด๋‹ค

boost ์ฝ”๋“œ๋Š” ์ฒจ๋ถ€ ๋งํฌ์—๋„ ๋‹ฌ์•„ ๋‘์—ˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๊ธธ...

์ƒ˜ํ”Œ์ฝ”๋“œ์— ๋™์ž‘์„ ํ™•์ธํ•  ๋กœ๊ทธ๋งŒ ๋ช‡ ์ค„ ์ถ”๊ฐ€ํ•ด์„œ ํ™•์ธํ•œ๊ฑด ๊นƒํ—™์— ์˜ฌ๋ ค๋‘์—ˆ๋‹น..

(github.com/bell-2/practice_01_boost)

๋‚ด๊ฐ€ ์ดํ•ดํ•˜๋Š”๋ฐ ์‹œ๊ฐ„ ๊ฑธ๋ฆฐ ๋ถ€๋ถ„๋งŒ ์ •๋ฆฌํ•˜๋Š”๊ฑธ๋กœ

 


1. ์–ด๋–ค Boost ์˜ˆ์ œ๋ฅผ ๋ณผ๊นŒ

 

- Async TCP Server (/boost_asio/example/echo/async_tcp_echo_server.cpp)

- Async TCP Client(/boost_asio/example/timeouts/async_tcp_client.cpp)

 

Timouts ํ•˜์œ„์— ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค ํ–ˆ๋Š”๋ฐ,

Server์šฉ ์ฝ”๋“œ๋Š” echo์— ํฌํ•จ๋˜์–ด์žˆ๋Š”๊ฒŒ ๋” ๋ณด๊ธฐ ํŽธํ•ด์„œ,

์š”๋ ‡๊ฒŒ ๋‘ ๊ฐœ๋ฅผ ์•Œ์•„๋ดค๋‹ค

 

sync๋Š” async ์ดํ•ดํ•˜๋ฉด ์‰ฝ๊ฒŒ ์ดํ•ด๊ฐ

 

2. Async TCP Server 

(1) Asio Service ๊ฐ์ฒด ์ƒ์„ฑ

 

int main(int argc, char* argv[])
{
    try
    {
        if (argc != 2)
        {
            std::cerr << "Usage: async_tcp_echo_server <port>\n";
            return 1;
        }

        boost::asio::io_service io_service;
        server s(io_service, atoi(argv[1]));
        io_service.run();
    }
    catch (std::exception& e)
    {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
}

 

main ํ•จ์ˆ˜๋ฅผ ๋จผ์ € ๋ณด๋ฉด,

Boost Asio๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” io_service ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ 

server๋ผ๋Š” ํด๋ž˜์Šค์— ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๋‹ค

 

server ํด๋ž˜์Šค์—์„œ io_service์— ๋ญ”๊ฐ€๋ฅผ ์…‹ํŒ… ํ•ด์ฃผ๋ ค๊ณ  ๋„ฃ๋Š”๊ฑธํ…Œ๊ณ ,

๊ทธ๋ ‡๊ฒŒ ์„ค์ •๋œ io_service์— ๋Œ€ํ•ด์„œ run()์„ ํ•ด์ฃผ๊ณ  ์žˆ๋‹ค

 

io_service ์‹œ์ž‘ → run()

io_service ์ข…๋ฃŒ → stop()

 

๊ทธ๋Ÿผ server ํด๋ž˜์Šค์—์„œ io_service์—๊ฒŒ ๋ญ˜ ํ–ˆ๋Š”์ง€ ๋ณด๋„๋ก ํ•˜์ž

 


(2) Accept ํ•˜๋Š” server Class

 

class server
{
    public:
        server(boost::asio::io_service& io_service, short port)
            : io_service_(io_service),
            acceptor_(io_service, tcp::endpoint(tcp::v4(), port))
    {
        session* new_session = new session(io_service_);
        acceptor_.async_accept(new_session->socket(),
                boost::bind(&server::handle_accept, this, new_session,
                    boost::asio::placeholders::error));
    }

     /* .... */
     private:
        boost::asio::io_service& io_service_;
        tcp::acceptor acceptor_;
};

 

server ํด๋ž˜์“ฐ์˜ ์ƒ์„ฑ์ž๋ถ€ํ„ฐ ๋ณด๋ฉด,

 io_service ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์˜ค๊ณ , ์„œ๋ฒ„๊ฐ€ ์—ด์–ด๋‘˜ port ์ •๋ณด๋Š” 

tcp::acceptor ๋กœ ์ฃผ๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค (io_service๋„)

 

ip::tcp:acceptor

์›๋ž˜ ์ด๋ฆ„์€ typedef basic_socket_acceptor <tcp> acceptor;์ด๋‹ค

(socket ํ†ต์‹ ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ทธ acceptor ๋งž์Šต๋‹ˆ๋‹ค)

 ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ ‘์†ํ•  Port๋ฅผ ์—ด์–ด๋‘๊ณ  ์—ฐ๊ฒฐ์— ๋Œ€ํ•ด acceptํ•  ์ค€๋น„๋ฅผ ํ•œ๋‹ค

boost ๊ณตํ™ˆ์— type๊ณผ member functions๋“ค์ด ์ •์˜ ๋˜์–ด์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•œ๋‹ค

 

basic_socket_acceptor::async_accept

๋น„๋™๊ธฐ ํ†ต์‹ ์˜ accept๋ผ ์ด๋ฆ„์ด async_accept๋‹ค

๋ง ๊ทธ๋Œ€๋กœ async accept๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ์—ญํ• ์ด๋‹ค

 

ํ•จ์ˆ˜ ๋ชจ์–‘์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

 

template< typename MoveAcceptHandler>
DEDUCED async_accept(
boost::asio::io_context & io_context, MoveAcceptHandler && handler); 

 

์ฃผ๋ชฉํ•ด์•ผํ• ๊ฑด ๋‘ ๋ฒˆ์งธ ์ธ์ž์ธ handler์ด๋‹ค

boost๋Š” asio ํ†ต์‹ ์˜ ์„ฑ๊ณต/์‹คํŒจ์˜ ๊ฒฐ๊ณผ๋ฅผ callback ํ˜•ํƒœ๋กœ ๋‘˜๋ ค์ค€๋‹ค

๊ทธ๋ž˜์„œ accept_async()๋ฅผ ์ˆ˜ํ–‰ํ•œ๊ฑฐ์—๋„ asio๋กœ๋ถ€ํ„ฐ ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜์‹ ํ• 

ํ•ธ๋“ค๋Ÿฌ๋ฅผ  ๋“ฑ๋ก์„ ํ•ด์ฃผ๋Š”๊ฑฐ๋‹ค

 

์œ„์˜ ์˜ˆ์ œ์—์„œ๋Š” boost::bind()๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋“ฑ๋กํ•  ํ•ธ๋“ค๋Ÿฌ์™€

ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ™์ด ๋„˜๊ฒจ์ฃผ๊ณ  ์žˆ๋‹ค

 

๊ทธ๋Ÿฌ๋ฉด  callback ํ•จ์ˆ˜๋กœ ๋“ฑ๋กํ•ด์ฃผ๊ณ  ์žˆ๋Š” server::handle_accept๋ฅผ ๋ด๋ณด์ž

 

void handle_accept(session* new_session,
         const boost::system::error_code& error)
 {
      if (!error)
      {
           new_session->start();

           cout << "START SESSION..." << endl;

           new_session = new session(io_service_);
           acceptor_.async_accept(new_session->socket(),
                       boost::bind(&server::handle_accept, this, new_session,
                       boost::asio::placeholders::error));
      }
      else
      {
    		delete new_session;
      }
}

 

asio์—์„œ accept๋ฅผ ํ•˜๊ณ ๋‚˜๋ฉด ์šฐ๋ฆฌ๊ฐ€ ๋“ฑ๋กํ•œ ์ด ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰์ด ๋œ๋‹ค

์„ฑ๊ณต/์‹คํŒจ์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋Š” boost::system::error_code ํ˜•ํƒœ๋กœ ๋ฐ›๊ฒŒ ๋œ๋‹ค

 

boost::system::error_code

error code์˜ ๋ฆฌ์ŠคํŠธ๋Š” enum ์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ๋‹ค

๊ฐ’์ด ๋ญ”์ง€ ์–ป์–ด์˜ค๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜ ๋‘๊ฐœ api๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค

error.value() → ์ˆซ์ž ํ˜•ํƒœ์˜ Error code

error.message() → ๋ฌธ์ž์—ด๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ

 

๋‹ค์‹œ ์ฝ”๋“œ๋กœ ๋Œ์•„๊ฐ€์„œ, 

์˜ˆ์ œ์—์„œ๋Š” session ํด๋ž˜์“ฐ์˜ ๊ฐ์ฒด๋ฅผ ๋ฐ›๊ณ , 

์—ฌ๋Ÿฌ ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ์—ฐ๊ฒฐ ์š”์ฒญ์ด ์˜ฌ ๊ฒƒ์„ ์œ„ํ•ด

์ƒˆ๋กœ์šด accept๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค

 


(3) session ์ƒ์„ฑ

 

๊ทธ๋Ÿฌ๋ฉด ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ์™€์˜ ์„ธ์…˜์ด ์ƒ์„ฑ๋˜๊ณ 

์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฝ๊ณ  ๊ทธ์— ๋Œ€ํ•ด ์‘๋‹ตํ•˜๋Š”

session ํด๋ž˜์Šค๋ฅผ ๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค

 

session* new_session = new session(io_service_);

 

async_accept์—์„œ๋„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„ฃ์–ด์ฃผ๊ณ  ์žˆ๋Š” new_session ๊ฐ์ฒด

 

class session
{
    public:
        session(boost::asio::io_service& io_service)
            : socket_(io_service)
        {
            cout << "NEW SESSION..." << endl;
        }
        /*....*/
 private:
        tcp::socket socket_;       
};

 

session ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์—์„œ๋Š” io_service ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์„œ

tcp::socket๋ฅผ ์ดˆ๊ธฐํ™” ํ•ด์ฃผ๊ณ  ์žˆ๋‹ค

 

ip::tcp::socket

์›๋ž˜ ์ด๋ฆ„์€ typedef basic_stream_socket< tcp >์ด๋‹ค

stream-oriented socket ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค๊ณ  ํ•œ๋‹ค

๋ง์ด ์–ด๋ ต์ง€๋งŒ, socket ํ†ต์‹ ์„ ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•ด์ฃผ๋Š” ๋ณ€์ˆ˜์ผ๋ฟ...!

fd๋ฅผ ํ†ตํ•ด์„œ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ...!

 

void handle_accept(session* new_session,
                const boost::system::error_code& error)
{
    /*...*/
	new_session->start();
    /*...*/
}

 

handle_accept์—์„œ session ํด๋ž˜์Šค ๊ฐ์ฒด์— ๋Œ€ํ•ด start()๋ผ๋Š”

ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๊ฒŒ ๋ณด์˜€์„๊ฑฐ๋‹ค

 

void start()
{
	socket_.async_read_some(boost::asio::buffer(data_, max_length),
	boost::bind(&session::handle_read, this,
                 boost::asio::placeholders::error,
                 boost::asio::placeholders::bytes_transferred));
}

 

์–˜๋Š” ๋ญํ•˜๋Š” ํ•จ์ˆ˜๋ƒ๋ฉด, ์•„๊นŒ ์œ„์—์„œ accept๋ฅผ ํ•˜๊ณ  ์‹ถ์œผ๋ฉด

accept ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜์‹ ํ•  ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•˜๋ผ๊ณ  ํ–ˆ์—ˆ๋‹ค

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ,

์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฝ๊ธฐ ์œ„ํ•ด read๋ฅผ ํ•˜๊ณ  ์‹ถ์œผ๋ฉด

read์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์„ ํ•ธ๋“ค๋Ÿฌ(session::handle_read)๋ฅผ

๋“ฑ๋กํ•ด์„œ ์‚ฌ์šฉํ•˜๋ž€๊ฑฐ๋‹ค

 

boost::asio::async_read_some

๋น„๋™๊ธฐ์‹ read๋ฅผ ์‹œ์ž‘ํ•˜๋„๋ก ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค

์ฐพ์•„๋ณด๋ฉด, readํ•˜๋Š” ํ•จ์ˆ˜๋Š” async_read(), async_read_untill() ๋“ฑ๋“ฑ

์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ์—ˆ์Œ

 

async_read_some ์›ํ˜•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

 

template<
    typename MutableBufferSequence,
    typename ReadHandler>
void async_read_some(
    const MutableBufferSequence & buffers,
    ReadHandler handler);

 

๋ญ์•ผ ๋ญ”๋ฐ? ํ•  ์ˆ˜ ์žˆ์ž ,ใ„ด

๋‹จ์ˆœํžˆ (์ฝ์€๊ฑฐ ์ €์žฅํ•  buffer, ๋“ฑ๋กํ•  ํ•ธ๋“ค๋Ÿฌ) ์ด๊ฑฐ๋‹ค

 

boost::asio::buffer

์ฝ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๋ฒ„ํผ์ด๋‹ค

ํ•„์š”ํ•˜๋ฉด ๋ณต์‚ฌํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, ๋ฉ”๋ชจ๋ฆฌ ์†Œ์œ ๊ถŒ์€ ํ˜ธ์ถœ์ž์— ์žˆ๋‹ค๊ณ  ํ•˜๋‹ˆ

์œ ํšจํ•œ ๋ฒ„ํผ์ธ์ง€ ์ž˜ ๋ณด๋„๋ก ํ•˜์ž

 

bytes_transferred

size_t ๋กœ ์ •์˜๋˜์–ด ์žˆ๊ณ , asio๊ฐ€ readํ•œ byte ์ˆ˜๋ฅผ

ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ†ตํ•ด ๊ฐ™์ด ์•Œ๋ ค์ค€๋‹ค

 


(4) ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ์ฝ์ž

 

๊ทธ๋Ÿฌ๋ฉด async_read_some์— ํ•ธ๋“ค๋Ÿฌ๋กœ ๋“ฑ๋กํ•œ

readํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋Œ๋ ค ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” handle_read()๋ฅผ ๋ณด๋„๋ก ํ•˜์ž

 

void handle_read(const boost::system::error_code& error,
                size_t bytes_transferred)
{
	if (!error)
	{
		cout << "RECV MSG:\n" << data_ << endl;

		boost::asio::async_write(socket_,
					boost::asio::buffer(data_, bytes_transferred),
					boost::bind(&session::handle_write, this,
					boost::asio::placeholders::error));
	}
	else
	{
		delete this;
	}
}

 

๋‚˜๋Š” ์˜ˆ์ œ ๋ณด๋ฉด์„œ ํ—ท๊ฐˆ๋ ธ๋˜๊ฒŒ

์•„๋‹ˆ ์™œ read๋ฅผ handleํ•˜๋Š” ํ•จ์ˆ˜์ธ๋ฐ

์—ฌ๊ธฐ์„œ write๋ฅผ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์€ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š”๊ฑฐ์ง€...?? ์˜€๋‹ค

 

๊ทผ๋ฐ ์ดํ•ด๋ฅผ ํ•˜๊ณ  ๋‚˜๋‹ˆ๊นŒ... ๋‹ค ์ฝ์—ˆ์œผ๋ฉด

์„œ๋ฒ„๋‹ˆ๊นŒ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ต ํ•ด์ค˜์•ผ ๋‹น์—ฐํ•œ๊ฑฐ์˜€๋‹ค

 

์—ฌ๊ธฐ์„œ๋„ ๋‹จ์ˆœํžˆ error ์ฒดํฌ๋งŒ ํ•ด์ฃผ๊ณ ,

์‘๋‹ต์„ ๋ณด๋‚ผ async_write() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ๊ณ  ์žˆ๋‹ด

 

๊ทผ๋ฐ ํ•ด๋‹น ์˜ˆ์ œ๋Š” ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฐ›์€ ๋ฉ”์‹œ์ง€๋ฅผ

echo ํ˜•ํƒœ๋กœ ์„œ๋ฒ„๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‹ค์‹œ ๋Œ๋ ค์ฃผ๋Š” ์˜ˆ์ œ๋ผ์„œ

bytes_transferred์™€ ๋ฐ›์€ buffer์˜ data๋ฅผ ๊ทธ๋Œ€๋กœ ๋‹ค์‹œ ๋ณด๋‚ด์ฃผ๊ณ  ์žˆ์œผ๋‹ˆ๊นŒ

์‹ค์ œ ์‚ฌ์šฉ ์‹œ์—๋Š” ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋ฅผ ์จ์„œ ํ•ด์•ผํ•œ๋‹ค

 

boost::asio::async_write

async_read()์™€ ๋น„์Šทํ•˜๊ฒŒ ์–˜๋„ write ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”

ํ•จ์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์ œ๊ณตํ•œ๋‹ค

(async_write_at, async_write_some ๋“ฑ)

 

์–˜๋„ ๋™์ผํ•˜๊ฒŒ

boost :: asio :: async_write (์†Œ์ผ“, boost :: asio :: buffer (๋ฐ์ดํ„ฐ, ํฌ๊ธฐ), ํ•ธ๋“ค๋Ÿฌ);

์ด๋ ‡๊ฒŒ ์จ์ฃผ๋ฉด ๋˜๊ฒ ๋‹ค

 


(5) ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ต์„ ๋ณด๋‚ด์ž

๋งˆ์ง€๋ง‰์œผ๋กœ ์‘๋‹ต ๋ณด๋‚ด๋Š” ์ฝ”๋“œ๋ฅผ ๋ณด๊ฒ ๋‹ค

 

void handle_write(const boost::system::error_code& error)
{
	if (!error)
	{
		socket_.async_read_some(boost::asio::buffer(data_, max_length),
				boost::bind(&session::handle_read, this,
				boost::asio::placeholders::error,
				boost::asio::placeholders::bytes_transferred));
	}
	else
	{
		delete this;
	}
}

 

์†Œ๋ฆ„๋‹๊ฒŒ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ž‘๋„ ๋น„์Šทํ•˜๊ฒŒ

error ์ฒดํฌ ํ•˜๊ณ , ์ž˜ ์‘๋‹ต์„ ๋ณด๋ƒˆ๋‹ค๋ฉด ๊ทธ ๋‹ค์Œ ๋ญํ• ์ง€๋ฅผ ์ž‘์„ฑํ•˜์˜€๋‹ค

 

์ด ์˜ˆ์ œ๋Š” ์—์ฝ” ์„œ๋ฒ„๋ผ ๊ณ„์† ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๊ณ  ๋ฐ›๊ณ  ํ•˜๋Š”๊ฑฐ๋ผ

๋‹ค์‹œ read๋ฅผ ํ•˜๋Ÿฌ ๊ฐ€๊ณ  ์žˆ์ง€๋งŒ

์ผ๋ฐ˜์ ์ธ ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด, ์—ฐ๊ฒฐ์„ ๋Š๊ณ  ์„ธ์…˜์ •๋ฆฌ๋ฅผ ํ•œ๋‹ค๊ฑฐ๋‚˜

๊ทธ๋Ÿฌ๋ฉด ๋  ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค

 


 

ํด๋ผ์ด์–ธํŠธ๋Š” ์–ธ์ œ ์ •๋ฆฌํ• ๊นŒ? ์กฐ๊ธˆ ๊ท€์ฐฎ์•„์ง„๋‹ค...

๊ทผ๋ฐ ์ด๋ฏธ ์„ธ์…˜์ •๋ฆฌํ•˜๋‹ค๊ฐ€ ์ฝ”์–ด ๋ช‡์‹ญ๊ฐœ ๋‚ด๊ณ  ์™”๋”๋‹ˆ

์ •๋ฆฌํ•˜๋Š”๊ฒŒ ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค ^^

 

์•„ ์ด๊ฒŒ ์ด๋ž˜์„œ ์ด๊ฑฐ์˜€๊ตฌ๋‚˜...๋ฅผ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค

์•„ ๋ฟŒ.๋“ฏ.ํ•˜.๋‹ค

 

ํ˜น์‹œ ์ž˜๋ชป๋œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๊ฑฐ๋‚˜ ๊ทธ๋Ÿฌ๋ฉด ์•Œ๋ ค์ฃผ์‹ญ์‡ผ

 


๐Ÿ˜„์ฐธ๊ณ  ์ž๋ฃŒ๐Ÿ˜„

www.boost.org/

 

Boost C++ Libraries

Welcome to Boost.org! Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work well with the C++ Standard Library. Boost libraries are intended to be widely useful, and usable across a broad spectrum of applications

www.boost.org

 

www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/timeouts/async_tcp_client.cpp

 

doc/html/boost_asio/example/timeouts/async_tcp_client.cpp - 1.45.0

 

www.boost.org

www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp

 

doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp - 1.52.0

 

www.boost.org

www.boost.org/doc/libs/1_76_0/doc/html/boost_asio.html

 

Boost.Asio - 1.76.0

Copyright © 2003-2021 Christopher M. Kohlhoff Boost.Asio is a cross-platform C++ library for network and low-level I/O programming that provides developers with a consistent asynchronous model using a modern C++ approach. Overview An overview of the featu

www.boost.org