void hpc_network_provider::do_accept() { while (true) { struct sockaddr_in addr; socklen_t addr_len = (socklen_t)sizeof(addr); socket_t s = ::accept(_listen_fd, (struct sockaddr*)&addr, &addr_len); if (s != -1) { ::dsn::rpc_address client_addr(ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port)); auto parser = new_message_parser(); auto rs = new hpc_rpc_session(s, parser, *this, client_addr); rpc_session_ptr s1(rs); rs->bind_looper(_looper); this->on_server_session_accepted(s1); } else { if (errno != EAGAIN && errno != EWOULDBLOCK) { derror("accept failed, err = %s", strerror(errno)); } break; } } }
rpc_session_ptr hpc_network_provider::create_client_session(::dsn::rpc_address server_addr) { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = 0; auto sock = create_tcp_socket(&addr); auto client = new hpc_rpc_session(sock, new_message_parser(), *this, server_addr, true); rpc_session_ptr c(client); client->bind_looper(_looper); return c; }
rpc_session_ptr hpc_network_provider::create_client_session(const ::dsn::rpc_address& server_addr) { auto matcher = new_client_matcher(); auto parser = new_message_parser(); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = 0; auto sock = create_tcp_socket(&addr); dassert(sock != -1, "create client tcp socket failed!"); auto client = new hpc_rpc_session(sock, parser, *this, server_addr, matcher); rpc_session_ptr c(client); client->bind_looper(_looper, true); return c; }
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; dsn_address_build_ipv4(client_addr.c_addr_ptr(), ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port)); auto parser = new_message_parser(); auto s = new hpc_rpc_session(_accept_sock, parser, *this, client_addr); rpc_session_ptr s1(s); s->bind_looper(_looper); this->on_server_session_accepted(s1); s->do_read(); } 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); } }