Exemple #1
0
        void asio_rpc_session::do_read(int sz)
        {
            add_ref();

            void* ptr = _parser->read_buffer_ptr((int)sz);
            int remaining = _parser->read_buffer_capacity();

            _socket->async_read_some(boost::asio::buffer(ptr, remaining),
                [this](boost::system::error_code ec, std::size_t length)
            {
                if (!!ec)
                {
                    derror("asio read from %s failed: %s", _remote_addr.to_string(), ec.message().c_str());
                    on_failure();
                }
                else
                {
                    int read_next;
                    message_ex* msg = _parser->get_message_on_receive((int)length, read_next);

                    while (msg != nullptr)
                    {
                        this->on_message_read(msg);
                        msg = _parser->get_message_on_receive(0, read_next);
                    }
                     
                    start_read_next(read_next);
                }

                release_ref();
            });
        }
Exemple #2
0
        void asio_rpc_session::connect()
        {
            if (try_connecting())
            {
                boost::asio::ip::tcp::endpoint ep(
                    boost::asio::ip::address_v4(_remote_addr.ip()), _remote_addr.port());

                add_ref();
                _socket->async_connect(ep, [this](boost::system::error_code ec)
                {
                    if (!ec)
                    {
                        dinfo("client session %s connected",
                            _remote_addr.to_string()
                            );

                        set_options();
                        set_connected();
                        on_send_completed();
                        start_read_next();
                    }
                    else
                    {
                        derror("client session connect to %s failed, error = %s",
                            _remote_addr.to_string(),
                            ec.message().c_str()
                            );
                        on_failure(true);
                    }
                    release_ref();
                });
            }
        }   
        void hpc_rpc_session::connect()
        {
            if (!try_connecting())
                return;
                        
            _connect_event.callback = [this](int err, uint32_t io_size, uintptr_t lpolp)
            {
                //dinfo("ConnectEx completed, err = %d, size = %u", err, io_size);
                if (err != ERROR_SUCCESS)
                {
                    dwarn("ConnectEx failed, err = %d", err);
                    this->on_failure(true);
                }
                else
                {
                    dinfo("client session %s connected",
                        _remote_addr.to_string()
                        );

                    set_connected();
                    on_send_completed();
                    start_read_next();
                }
                this->release_ref(); // added before ConnectEx
            };
            memset(&_connect_event.olp, 0, sizeof(_connect_event.olp));

            struct sockaddr_in addr;
            addr.sin_family = AF_INET;
            addr.sin_addr.s_addr = htonl(_remote_addr.ip());
            addr.sin_port = htons(_remote_addr.port());

            this->add_ref(); // released in _connect_event.callback
            BOOL rt = s_lpfnConnectEx(
                _socket,
                (struct sockaddr*)&addr,
                (int)sizeof(addr),
                0,
                0,
                0,
                &_connect_event.olp
                );

            if (!rt && (WSAGetLastError() != ERROR_IO_PENDING))
            {
                dwarn("ConnectEx failed, err = %d", ::WSAGetLastError());
                this->release_ref();

                on_failure(true);
            }
        }
Exemple #4
0
 asio_rpc_session::asio_rpc_session(
     asio_network_provider& net,
     ::dsn::rpc_address remote_addr,
     std::shared_ptr<boost::asio::ip::tcp::socket>& socket,
     std::unique_ptr<message_parser>&& parser,
     bool is_client
     )
     :
     rpc_session(net, remote_addr, std::move(parser), is_client),
     _socket(socket)
 {
     set_options();
     if (!is_client) start_read_next();
 }
        void hpc_rpc_session::do_read(int sz)
        {
            add_ref();
            _read_event.callback = [this](int err, uint32_t length, uintptr_t lolp)
            {
                //dinfo("WSARecv completed, err = %d, size = %u", err, length);
                dassert((LPOVERLAPPED)lolp == &_read_event.olp, "must be exact this overlapped");
                if (err != ERROR_SUCCESS)
                {
                    dwarn("WSARecv failed, err = %d", err);
                    on_failure();
                }
                else
                {
                    int read_next;
                    message_ex* msg = _parser->get_message_on_receive((int)length, read_next);

                    while (msg != nullptr)
                    {
                        if (msg->header->from_address.is_invalid())
                            msg->header->from_address = _remote_addr;
                        this->on_read_completed(msg);
                        msg = _parser->get_message_on_receive(0, read_next);
                    }

                    if (read_next == -1)
                    {
                        derror("(s = %d) recv failed, err = %s", _socket, "message with wrong checksum");
                        on_failure();
                    }
                    else
                    {
                        start_read_next(read_next);
                    }
                }

                release_ref();
            };
            memset(&_read_event.olp, 0, sizeof(_read_event.olp));

            WSABUF buf[1];

            void* ptr = _parser->read_buffer_ptr((int)sz);
            int remaining = _parser->read_buffer_capacity();
            buf[0].buf = (char*)ptr;
            buf[0].len = remaining;

            DWORD bytes = 0;
            DWORD flag = 0;
            int rt = WSARecv(
                _socket,
                buf,
                1,
                &bytes,
                &flag,
                &_read_event.olp,
                NULL
                );
            
            if (SOCKET_ERROR == rt && (WSAGetLastError() != ERROR_IO_PENDING))
            {
                dwarn("WSARecv failed, err = %d", ::WSAGetLastError());
                release_ref();
                on_failure();
            }

            //dinfo("WSARecv called, err = %d", rt);
        }
        void hpc_network_provider::do_accept()
        {
            socket_t s = create_tcp_socket(nullptr);
            dassert(s != INVALID_SOCKET, "cannot create socket for accept");

            _accept_sock = s;            
            _accept_event.callback = [this](int err, uint32_t size, uintptr_t lpolp)
            {
                //dinfo("accept completed, err = %d, size = %u", err, size);
                dassert(&_accept_event.olp == (LPOVERLAPPED)lpolp, "must be this exact overlap");
                if (err == ERROR_SUCCESS)
                {
                    setsockopt(_accept_sock,
                        SOL_SOCKET,
                        SO_UPDATE_ACCEPT_CONTEXT,
                        (char *)&_listen_fd,
                        sizeof(_listen_fd)
                        );

                    struct sockaddr_in addr;
                    memset((void*)&addr, 0, sizeof(addr));

                    addr.sin_family = AF_INET;
                    addr.sin_addr.s_addr = INADDR_ANY;
                    addr.sin_port = 0;

                    int addr_len = sizeof(addr);
                    if (getpeername(_accept_sock, (struct sockaddr*)&addr, &addr_len)
                        == SOCKET_ERROR)
                    {
                        dassert(false, "getpeername failed, err = %d", ::WSAGetLastError());
                    }

                    ::dsn::rpc_address client_addr(ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port));

                    auto s = new hpc_rpc_session(_accept_sock, new_message_parser(), *this, client_addr, false);
                    rpc_session_ptr s1(s);
                    s->bind_looper(_looper);

                    this->on_server_session_accepted(s1);

                    s->start_read_next();
                }
                else
                {
                    closesocket(_accept_sock);
                }

                do_accept();
            };
            memset(&_accept_event.olp, 0, sizeof(_accept_event.olp));

            DWORD bytes;
            BOOL rt = s_lpfnAcceptEx(
                _listen_fd, s,
                _accept_buffer,
                0,
                (sizeof(struct sockaddr_in) + 16),
                (sizeof(struct sockaddr_in) + 16),
                &bytes,
                &_accept_event.olp
                );

            if (!rt && (WSAGetLastError() != ERROR_IO_PENDING))
            {
                dassert(false, "AcceptEx failed, err = %d", ::WSAGetLastError());
                closesocket(s);
            }
        }