| 60 | } |
| 61 | |
| 62 | void openhd::TCPServer::loop_accept() { |
| 63 | struct sockaddr_in sockaddr {}; |
| 64 | if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { |
| 65 | m_console->warn("open socket failed"); |
| 66 | return; |
| 67 | } |
| 68 | int opt = 1; |
| 69 | if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, |
| 70 | sizeof(opt))) { |
| 71 | m_console->warn("setsockopt failed"); |
| 72 | close(server_fd); |
| 73 | return; |
| 74 | } |
| 75 | sockaddr.sin_family = AF_INET; |
| 76 | sockaddr.sin_addr.s_addr = INADDR_ANY; |
| 77 | sockaddr.sin_port = htons(m_config.port); |
| 78 | if (bind(server_fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) { |
| 79 | m_console->warn("bind failed"); |
| 80 | close(server_fd); |
| 81 | return; |
| 82 | } |
| 83 | // signal readiness to accept clients |
| 84 | if (listen(server_fd, 5) < 0) { |
| 85 | m_console->warn("listen failed"); |
| 86 | close(server_fd); |
| 87 | return; |
| 88 | } |
| 89 | const int sockaddr_len = sizeof(sockaddr); |
| 90 | while (m_keep_accept_thread_alive) { |
| 91 | const auto accept_result = accept(server_fd, (struct sockaddr*)&sockaddr, |
| 92 | (socklen_t*)&sockaddr_len); |
| 93 | if (accept_result < 0) { |
| 94 | m_console->debug("accept failed"); |
| 95 | close(server_fd); |
| 96 | return; |
| 97 | } |
| 98 | const std::string client_ip = inet_ntoa(sockaddr.sin_addr); |
| 99 | const int client_port = ntohs(sockaddr.sin_port); |
| 100 | m_console->debug("accepted client,sockfd:{}, ip:{}, port:{}", accept_result, |
| 101 | client_ip, client_port); |
| 102 | auto new_client = std::make_shared<ConnectedClient>(); |
| 103 | new_client->sock_fd = accept_result; |
| 104 | new_client->ip = client_ip; |
| 105 | new_client->port = client_port; |
| 106 | new_client->keep_rx_looping = true; |
| 107 | new_client->parent = this; |
| 108 | new_client->rx_loop_thread = std::make_shared<std::thread>( |
| 109 | &TCPServer::ConnectedClient::loop_rx, new_client.get()); |
| 110 | on_external_device(client_ip, client_port, true); |
| 111 | { |
| 112 | std::lock_guard<std::mutex> guard(m_clients_list_mutex); |
| 113 | m_clients_list.push_back(new_client); |
| 114 | } |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | void openhd::TCPServer::send_message_to_all_clients(const uint8_t* data, |
| 119 | int data_len) { |