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