sock_handle_t next_unused_tcp() { for (sock_handle_t i=0; i<SOCKET_COUNT; i++) { if (!tcp_from(i).is_open()) return i; } return -1; }
sock_handle_t start_accept() { sock_handle_t handle = next_unused_tcp(); if (!socket_handle_valid(handle)) return handle; ip::tcp::socket& sock = tcp_from(handle); acceptor.accept(sock); return handle; }
sock_handle_t accept() { sock_handle_t handle = next_unused_tcp(); if (!socket_handle_valid(handle)) return handle; ip::tcp::socket& sock = tcp_from(handle); acceptor.accept(sock, ec); return !ec ? handle : socket_handle_invalid(); }
sock_result_t socket_send(sock_handle_t sd, const void* buffer, socklen_t len) { auto& socket = tcp_from(sd); if (!is_valid(socket)) return -1; try { sock_result_t result = write(socket, boost::asio::buffer(buffer, len)); return result; } catch (boost::system::system_error e) { return -1; } }
int32_t socket_connect(sock_handle_t sd, const sockaddr_t *addr, long addrlen) { auto& handle = tcp_from(sd); if (!is_valid(handle)) return -1; unsigned port = addr->sa_data[0] << 8 | addr->sa_data[1]; // 2-5 are IP address in network byte order const uint8_t* dest = addr->sa_data+2; ip::address_v4::bytes_type address = {{ dest[0], dest[1], dest[2], dest[3] }}; ip::tcp::endpoint endpoint(boost::asio::ip::address_v4(address),port); handle.connect(endpoint, ec); bool open = handle.is_open(); return ec.value(); }
sock_result_t socket_receive(sock_handle_t sd, void* buffer, socklen_t len, system_tick_t _timeout) { auto& handle = tcp_from(sd); if (!is_valid(handle)) return -1; boost::asio::socket_base::bytes_readable command(true); handle.io_control(command); std::size_t available = command.get(); sock_result_t result = 0; available = handle.read_some(boost::asio::buffer(buffer, len), ec); result = ec.value() ? -abs(ec.value()) : available; if (ec.value()) { if (ec.value() == boost::system::errc::resource_deadlock_would_occur || // EDEADLK (35) ec.value() == boost::system::errc::resource_unavailable_try_again) { // EAGAIN (11) result = 0; // No data available } else { DEBUG("socket receive error: %d %s, read=%d", ec.value(), ec.message().c_str(), available); } } return result; }