客户端服务器简单示例非阻塞 [英] client server simple example nonblocking

查看:86
本文介绍了客户端服务器简单示例非阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此代码中,服务器不接受任何其他客户端,而仅接受一个客户端.

In this code, the server is not accepting any more client but only one.

假设一个客户端已被接受,并且服务器收到消息并向客户端发送"HELLO"后,服务器不接受另一个客户端,为什么?

Say one client has been accepted and after the server got a message and sent "HELLO" to the client, the server is not accepting another client, why?

#include <boost\asio.hpp>
#include <boost\bind.hpp>
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

void accept_handle(const boost::system::error_code& eCode, boost::asio::ip::tcp::socket* client, boost::asio::ip::tcp::acceptor* server);
void read_handle(const boost::system::error_code& eCode, std::size_t bytes, boost::asio::ip::tcp::socket* client, boost::asio::ip::tcp::acceptor* server);
void write_handle(const boost::system::error_code& eCode, std::size_t bytes, boost::asio::ip::tcp::acceptor* server);

int main(int argc, char** argv)
{
    boost::asio::io_service service;
    boost::asio::ip::tcp::acceptor server(service);

    boost::system::error_code eCode;
    boost::asio::ip::tcp::endpoint point(boost::asio::ip::address::from_string("127.0.0.1"), 12345);

    server.open(point.protocol());

    server.bind(point);
    server.listen(987);

    boost::asio::ip::tcp::socket connection(service);
    server.async_accept(connection, boost::bind(accept_handle, _1, &connection, &server));

    service.run();

    system("pause");
    return 0;
}

void write_handle(const boost::system::error_code& eCode, std::size_t bytes, boost::asio::ip::tcp::acceptor* server)
{
    if (!eCode)
    {
        cout << "Written" << endl;
        cout << "Done" << endl;
        boost::asio::ip::tcp::socket connection(server->get_io_service());
        server->async_accept(connection, boost::bind(accept_handle, _1, &connection, server));


    }
        else {
        cout << "NOT written" << endl;
    }
}

void read_handle(const boost::system::error_code& eCode, std::size_t bytes, boost::asio::ip::tcp::socket* client, boost::asio::ip::tcp::acceptor* server)
{
    if (!eCode)
    {
        cout << "Read" << endl;
        client->async_write_some(boost::asio::buffer("HELLO"), boost::bind(write_handle, _1, _2, server));
    }else{
        cout << "NOT read" << endl;
    }
}

void accept_handle(const boost::system::error_code& eCode, boost::asio::ip::tcp::socket* client, boost::asio::ip::tcp::acceptor* server)
{
    if (!eCode)
    {
        char data[6];
        cout << "Connected" << endl;

        client->async_read_some(boost::asio::buffer(data, 6), boost::bind(read_handle, _1, _2, client, server));
        cout << data << endl;
    }
    else {
        cout << "NOT connected" << endl;
    }
}

注意->我做了一个函数,该函数首先获取来自客户端的消息的大小,以便服务器可以分配足够的内存,然后获取消息本身,所以第二个问题是如何在函数中使用我的函数async_read_some/async_write_some ???我认为这个想法先得到消息的大小,然后再使用s来传递消息本身不是很好,为此又有了另一个想法?

NOTE-> I did a function which first gets the size of the message coming from a client so that the server can allocate enough memory and after that gets the message itself, so the second problem is how can i use my function in async_read_some / async_write_some??? i think this idea getting first the size of the message and then the message itself using s is not very good, have got another ideas for it???

推荐答案

首先,请确保您已处理并显示错误:

First, make sure you handle and show errors:

std::cout << "NOT written: " << eCode.message() << "\n";
// ...
std::cout << "NOT read: " << eCode.message() << "\n";
// ...
std::cout << "NOT connected: " << eCode.message() << "\n";

接下来,启用Asan/UBSan! -fsanitze=undefined,address已经在第一个连接上给出了此信息:

Next, enable Asan/UBSan! -fsanitze=undefined,address gives this on the first connection already:

=================================================================
==409==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc048aa8d6 at pc 0x7f82f079043e bp 0x7ffc048aa790 sp 0x7ffc048a9f38
READ of size 7 at 0x7ffc048aa8d6 thread T0
    #0 0x7f82f079043d  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5143d)
    #1 0x7f82f02c7398 in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x114398)
    #2 0x405338 in accept_handle(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*) /home/sehe/Projects/stackoverflow/test.cpp:58
    #3 0x444789 in void boost::_bi::list3<boost::arg<1>, boost::_bi::value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*>, boost::_bi::value<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*> >::operator()<void (*)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::rrlist1<boost::system::error_code const&> >(boost::_bi::type<void>, void (*&)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::rrlist1<boost::system::error_code const&>&, int) (/home/sehe/Projects/stackoverflow/sotest+0x444789)
    #4 0x443d14 in void boost::_bi::bind_t<void, void (*)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::list3<boost::arg<1>, boost::_bi::value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*>, boost::_bi::value<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*> > >::operator()<boost::system::error_code const&>(boost::system::error_code const&) (/home/sehe/Projects/stackoverflow/sotest+0x443d14)
    #5 0x4439ab in boost::asio::detail::binder1<boost::_bi::bind_t<void, void (*)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::list3<boost::arg<1>, boost::_bi::value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*>, boost::_bi::value<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*> > >, boost::system::error_code>::operator()() (/home/sehe/Projects/stackoverflow/sotest+0x4439ab)
    #6 0x442f19 in void boost::asio::asio_handler_invoke<boost::asio::detail::binder1<boost::_bi::bind_t<void, void (*)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::list3<boost::arg<1>, boost::_bi::value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*>, boost::_bi::value<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*> > >, boost::system::error_code> >(boost::asio::detail::binder1<boost::_bi::bind_t<void, void (*)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::list3<boost::arg<1>, boost::_bi::value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*>, boost::_bi::value<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*> > >, boost::system::error_code>&, ...) (/home/sehe/Projects/stackoverflow/sotest+0x442f19)
    #7 0x441532 in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder1<boost::_bi::bind_t<void, void (*)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::list3<boost::arg<1>, boost::_bi::value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*>, boost::_bi::value<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*> > >, boost::system::error_code>, boost::_bi::bind_t<void, void (*)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::list3<boost::arg<1>, boost::_bi::value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*>, boost::_bi::value<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*> > > >(boost::asio::detail::binder1<boost::_bi::bind_t<void, void (*)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::list3<boost::arg<1>, boost::_bi::value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*>, boost::_bi::value<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*> > >, boost::system::error_code>&, boost::_bi::bind_t<void, void (*)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::list3<boost::arg<1>, boost::_bi::value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*>, boost::_bi::value<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*> > >&) (/home/sehe/Projects/stackoverflow/sotest+0x441532)
    #8 0x43f64b in boost::asio::detail::reactive_socket_accept_op<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::ip::tcp, boost::_bi::bind_t<void, void (*)(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*), boost::_bi::list3<boost::arg<1>, boost::_bi::value<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*>, boost::_bi::value<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*> > > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) (/home/sehe/Projects/stackoverflow/sotest+0x43f64b)
    #9 0x41326f in boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task_io_service&, boost::system::error_code const&, unsigned long) (/home/sehe/Projects/stackoverflow/sotest+0x41326f)
    #10 0x41fe4b in boost::asio::detail::epoll_reactor::descriptor_state::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) (/home/sehe/Projects/stackoverflow/sotest+0x41fe4b)
    #11 0x41326f in boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task_io_service&, boost::system::error_code const&, unsigned long) (/home/sehe/Projects/stackoverflow/sotest+0x41326f)
    #12 0x42463d in boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) (/home/sehe/Projects/stackoverflow/sotest+0x42463d)
    #13 0x42286c in boost::asio::detail::task_io_service::run(boost::system::error_code&) (/home/sehe/Projects/stackoverflow/sotest+0x42286c)
    #14 0x425aba in boost::asio::io_service::run() (/home/sehe/Projects/stackoverflow/sotest+0x425aba)
    #15 0x40465d in main /home/sehe/Projects/stackoverflow/test.cpp:28
    #16 0x7f82eecb682f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #17 0x404178 in _start (/home/sehe/Projects/stackoverflow/sotest+0x404178)

Address 0x7ffc048aa8d6 is located in stack of thread T0 at offset 230 in frame
    #0 0x405082 in accept_handle(boost::system::error_code, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >*) /home/sehe/Projects/stackoverflow/test.cpp:52

  This frame has 4 object(s):
    [32, 48) '<unknown>'
    [96, 120) '<unknown>'
    [160, 192) '<unknown>'
    [224, 230) 'data' <== Memory access at offset 230 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5143d) 
Shadow bytes around the buggy address:
  0x10000090d4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000090d4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000090d4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000090d4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
  0x10000090d500: f1 f1 f8 f8 f2 f2 f2 f2 f2 f2 f8 f8 f8 f2 f2 f2
=>0x10000090d510: f2 f2 00 00 00 00 f2 f2 f2 f2[06]f2 f2 f2 00 00
  0x10000090d520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000090d530: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 01 f2
  0x10000090d540: f2 f2 f2 f2 f2 f2 00 f2 f2 f2 00 00 00 00 00 00
  0x10000090d550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000090d560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==409==ABORTING

原因:

在您的handle_accept中,您拥有

std::cout << data << "\n";

这将打印data,但是没有零终止符.添加:

This prints data but there is no zero-termination. Adding it:

char data[7] = {0};

导致下一次违规:

=================================================================
==2055==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7ffe09a1c640 at pc 0x7f45551cb739 bp 0x7ffe09a1bd20 sp 0x7ffe09a1b4c8
WRITE of size 6 at 0x7ffe09a1c640 thread T0
    #0 0x7f45551cb738  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x3a738)
    #1 0x7f455522e305  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x9d305)
    #2 0x7f455522ef43 in __interceptor_recvmsg (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x9df43)
    #3 0x42828d in boost::asio::detail::socket_ops::recv(int, iovec*, unsigned long, int, boost::system::error_code&) (/home/sehe/Projects/stackoverflow/sotest+0x42828d)
    #4 0x428554 in boost::asio::detail::socket_ops::non_blocking_recv(int, iovec*, unsigned long, int, bool, boost::system::error_code&, unsigned long&) (/home/sehe/Projects/stackoverflow/sotest+0x428554)
    #5 0x442938 in boost::asio::detail::reactive_socket_recv_op_base<boost::asio::mutable_buffers_1>::do_perform(boost::asio::detail::reactor_op*) (/home/sehe/Projects/stackoverflow/sotest+0x442938)
    #6 0x4138b4 in boost::asio::detail::reactor_op::perform() (/home/sehe/Projects/stackoverflow/sotest+0x4138b4)
    #7 0x41fbe6 in boost::asio::detail::epoll_reactor::descriptor_state::perform_io(unsigned int) (/home/sehe/Projects/stackoverflow/sotest+0x41fbe6)
    #8 0x41fe55 in boost::asio::detail::epoll_reactor::descriptor_state::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) (/home/sehe/Projects/stackoverflow/sotest+0x41fe55)
    #9 0x4132e3 in boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task_io_service&, boost::system::error_code const&, unsigned long) (/home/sehe/Projects/stackoverflow/sotest+0x4132e3)
    #10 0x4246b1 in boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) (/home/sehe/Projects/stackoverflow/sotest+0x4246b1)
    #11 0x4228e0 in boost::asio::detail::task_io_service::run(boost::system::error_code&) (/home/sehe/Projects/stackoverflow/sotest+0x4228e0)
    #12 0x425b2e in boost::asio::io_service::run() (/home/sehe/Projects/stackoverflow/sotest+0x425b2e)
    #13 0x40465d in main /home/sehe/Projects/stackoverflow/test.cpp:28
    #14 0x7f455370882f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #15 0x404178 in _start (/home/sehe/Projects/stackoverflow/sotest+0x404178)

Address 0x7ffe09a1c640 is located in stack of thread T0 at offset 16 in frame
    #0 0x647361647370  (<unknown module>)

  This frame has 2 object(s):
    [32, 48) '<unknown>' <== Memory access at offset 16 underflows this variable
    [96, 152) 'msg'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-underflow (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x3a738) 
Shadow bytes around the buggy address:
  0x10004133b870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004133b880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004133b890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004133b8a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10004133b8b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10004133b8c0: 00 00 00 00 00 00 f1 f1[f1]f1 00 00 f2 f2 f2 f2
  0x10004133b8d0: f2 f2 00 00 00 00 00 00 00 f2 00 00 00 00 00 00
  0x10004133b8e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
  0x10004133b8f0: f1 f1 00 00 f2 f2 f2 f2 f2 f2 00 00 f2 f2 f2 f2
  0x10004133b900: f2 f2 00 00 f2 f2 f2 f2 f2 f2 00 00 f2 f2 00 00
  0x10004133b910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==2055==ABORTING

这是由于以下事实造成的:

This is caused by the fact that:

char data[7] = {0};
std::cout << "Connected\n";

client->async_read_some(ba::buffer(data, 6), boost::bind(read_handle, _1, _2, client, server));

ba::buffer(data, 6)传递给异步操作,但是异步操作不会在accept_handle返回之前完成,因此data不再存在.哎呀.

Passes ba::buffer(data, 6) to an asynchronous operation, but the asynchronous operation doesn't complete before accept_handle returns, so data doesn't exist anymore. OOPS.

您当然可以将其设置为全局变量,但这意味着您不能有多个连接.现在,让我们执行此操作(稍后将对其进行修复):

You can of course make it a global variable, but that means you cannot have more than one connection. For now, let's do this (we'll fix it later):

static char data[7]; // TODO FIXME global data shared across connections
void accept_handle(error_code eCode, tcp::socket *client, tcp::acceptor *server) {
    if (!eCode) {
        std::fill_n(data, sizeof(data), '\0');
        std::cout << "Connected\n";

        client->async_read_some(ba::buffer(data, 6), boost::bind(read_handle, _1, _2, client, server));
        std::cout << data << "\n";
    } else {
        std::cout << "NOT connected: " << eCode.message() << "\n";
    }
}

现在至少第一个连接成功".下次连接,BOOM:

Now at least the first connection "succeeds". Next connection, BOOM:

/home/sehe/custom/boost_1_65_0/boost/asio/basic_io_object.hpp:225:13: runtime error: reference binding to misaligned address 0x000000000012 for type 'struct service_type', which requires 8 byte alignment
0x000000000012: note: pointer points here
<memory cannot be printed>
/home/sehe/custom/boost_1_65_0/boost/asio/basic_socket.hpp:331:36: runtime error: member call on misaligned address 0x000000000012 for type 'struct service_type', which requires 8 byte alignment
0x000000000012: note: pointer points here
<memory cannot be printed>
/home/sehe/custom/boost_1_65_0/boost/asio/basic_socket.hpp:331:36: runtime error: member access within misaligned address 0x000000000012 for type 'struct service_type', which requires 8 byte alignment
0x000000000012: note: pointer points here
<memory cannot be printed>
ASAN:DEADLYSIGNAL
=================================================================
==5056==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000012 (pc 0x000000443294 bp 0x7fffc08266d0 sp 0x7fffc08266a0 T0)
==5056==The signal is caused by a READ memory access.
==5056==Hint: address points to the zero page.
    #0 0x443293 in boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::assign(boost::asio::ip::tcp const&, int const&, boost::system::error_code&) (/home/sehe/Projects/stackoverflow/sotest+0x443293)
    #1 0x441e20 in boost::asio::detail::reactive_socket_accept_op_base<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::ip::tcp>::do_perform(boost::asio::detail::reactor_op*) (/home/sehe/Projects/stackoverflow/sotest+0x441e20)
    #2 0x4138f6 in boost::asio::detail::reactor_op::perform() (/home/sehe/Projects/stackoverflow/sotest+0x4138f6)
    #3 0x41fc28 in boost::asio::detail::epoll_reactor::descriptor_state::perform_io(unsigned int) (/home/sehe/Projects/stackoverflow/sotest+0x41fc28)
    #4 0x41fe97 in boost::asio::detail::epoll_reactor::descriptor_state::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) (/home/sehe/Projects/stackoverflow/sotest+0x41fe97)
    #5 0x413325 in boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task_io_service&, boost::system::error_code const&, unsigned long) (/home/sehe/Projects/stackoverflow/sotest+0x413325)
    #6 0x4246f3 in boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) (/home/sehe/Projects/stackoverflow/sotest+0x4246f3)
    #7 0x422922 in boost::asio::detail::task_io_service::run(boost::system::error_code&) (/home/sehe/Projects/stackoverflow/sotest+0x422922)
    #8 0x425b70 in boost::asio::io_service::run() (/home/sehe/Projects/stackoverflow/sotest+0x425b70)
    #9 0x40465d in main /home/sehe/Projects/stackoverflow/test.cpp:28
    #10 0x7f33164b182f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #11 0x404178 in _start (/home/sehe/Projects/stackoverflow/sotest+0x404178)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/home/sehe/Projects/stackoverflow/sotest+0x443293) in boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::assign(boost::asio::ip::tcp const&, int const&, boost::system::error_code&)
==5056==ABORTING

问题类似:

tcp::socket connection(server->get_io_service());
server->async_accept(connection, boost::bind(accept_handle, _1, &connection, server));

您要再次将局部变量传递到async_accept中.应用类似的修复程序:

You're passing a local variable into async_accept again. Applying a similar fix:

void do_accept(tcp::acceptor& server) {
    static tcp::socket connection(server.get_io_service()); // TODO FIXME global data shared

    if (connection.is_open())
        connection.close();

    server.async_accept(connection, boost::bind(accept_handle, _1, &connection, &server));
}

现在您的服务器可以连续接受多个连接:

Now your server can accept several connections in succession:

在Coliru上直播

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <iostream>

namespace ba = boost::asio;
using ba::ip::tcp;
using boost::system::error_code;

void accept_handle(error_code eCode, tcp::socket *client, tcp::acceptor *server);
void read_handle(error_code eCode, std::size_t bytes, tcp::socket *client, tcp::acceptor *server);
void write_handle(error_code eCode, std::size_t bytes, tcp::acceptor *server);

void do_accept(tcp::acceptor& a);

int main() {
    ba::io_service service;
    tcp::acceptor server(service);

    tcp::endpoint endpoint{{}, 12345};

    server.open(endpoint.protocol());
    server.set_option(tcp::acceptor::reuse_address(true));

    server.bind(endpoint);
    server.listen();

    do_accept(server);

    service.run();
}

void do_accept(tcp::acceptor& server) {
    static tcp::socket connection(server.get_io_service()); // TODO FIXME global data shared

    if (connection.is_open())
        connection.close();

    server.async_accept(connection, boost::bind(accept_handle, _1, &connection, &server));
}

static char data[7]; // TODO FIXME global data shared across connections
void accept_handle(error_code eCode, tcp::socket *client, tcp::acceptor *server) {
    if (!eCode) {
        std::fill_n(data, sizeof(data), '\0');
        std::cout << "Connected\n";

        client->async_read_some(ba::buffer(data, 6), boost::bind(read_handle, _1, _2, client, server));
        std::cout << data << "\n";
    } else {
        std::cout << "NOT connected: " << eCode.message() << "\n";
    }
}

void read_handle(error_code eCode, std::size_t bytes, tcp::socket *client, tcp::acceptor *server) {
    if (!eCode) {
        std::cout << "Read\n";
        client->async_write_some(ba::buffer("HELLO\n"), boost::bind(write_handle, _1, _2, server));
    } else {
        std::cout << "NOT read: " << eCode.message() << "\n";
    }
}

void write_handle(error_code eCode, std::size_t bytes, tcp::acceptor *server) {
    if (!eCode) {
        std::cout << "Written\n";
        std::cout << "Done\n";

        do_accept(*server);
    } else {
        std::cout << "NOT written: " << eCode.message() << "\n";
    }
}

这篇关于客户端服务器简单示例非阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆