щас напишу рабочюю версию и _свой_ исходник, кто разберется тому респект! --- Сообщение объединено, 19 фев 2022 --- 1 ое это мой файлик который _не_работает_ (((((( 2 файлик который _работает_ ))
сперва так сбрутфорсить код, чтобы конпилился, потом так - чтобы работал, а уж как он работает - да какая вообще разница)
Ошибка может и есть, но ты только руки не опускай, это - самое главное, верь в себя и у тебя все получится!
В общем народ... accept и connect виснет, результирующие функции... что делать? может защиты какие то...
Обратите внимание, вот здесь идеальный пример того, как новичок может задать вопрос. Вот пример похуже, автор кардинально плывет в теме, но все-таки он старается, добавляет скрины и пытается описать то как он понимает происходящее. Если у вас, как и у многих тут, есть нарушения, не позволяющие внятно сформулировать мысли, наверное стоит это упомянуть, у форумчан может появиться какое-то желание вам помогать. Потому что сейчас ваш стиль выглядит как неуважение и небрежность по отношению к своему и чужому потраченному времени.
Давно уже не брал в руки сокеты, но глянул сейчас в свой код на Си и принцип в следующем - серверный сокет типа TCP/IP (STREAM) создаётся через socket/bind/listen - он теперь слушает попытки установить входящее соединение по серверному своему порту. В серверный такой сокет не надо делать send/recv. С ним надо делать accept который в случае попытки входящего соединения вернёт уже клиентский сокет - вот именно с ним надо делать send/recv. Один серверный сокет выполняет рукопожатие и даёт любое число клиенских сокетов point-to-point по которым уже происходит общение по своим клиентским портам. И любая функция может вернуть неудачу - все надо проверять на возвращаемые значения чтобы понимать на каком этапе происходит ошибка. Так тот же серверный сокет может не забиндится на порт если есть другой процесс уже занявший это число.
Код (C++): /*static */ bool simple_server::set_socket_blocking( SOCKET fd, bool blocking ) { if ( fd == INVALID_SOCKET ) return false; #ifdef _WIN32 unsigned long mode = blocking ? 0 : 1; return ( ioctlsocket( fd, FIONBIO, &mode ) == 0 ) ? true : false; #else int flags = fcntl( fd, F_GETFL, 0 ); if ( flags == -1 ) return false; flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); return ( fcntl( fd, F_SETFL, flags ) == 0 ) ? true : false; #endif } ... void simple_server::cleanup() { if ( wsa_started ) { if ( client_s != INVALID_SOCKET ) { closesocket( client_s ); client_s = INVALID_SOCKET; } if ( server_s != INVALID_SOCKET ) { closesocket( server_s ); server_s = INVALID_SOCKET; } if ( bcast_s != INVALID_SOCKET ) { closesocket( bcast_s ); bcast_s = INVALID_SOCKET; } WSACleanup(); wsa_started = false; } } // 0 - success, <0 - errors int simple_server::init( int port, int bcastp, const char *bcast_saddr, const char *bcast_msg ) { WSAData wData; SOCKADDR_IN addr; int res = 0; // ok char broadcast = '1'; this->bcast_msg = bcast_msg; //writeToLog( "BCASTMSGIS:" + this->bcast_msg ); error_msg.clear(); data.clear(); if ( WSAStartup( MAKEWORD(2, 2), &wData ) != 0 ) { error_msg = L"WSA Startup failure (" + getWSAErrorString() + L")"; res = -1; goto fail; } wsa_started = true; // Setup server socket addr.sin_addr.S_un.S_addr = INADDR_ANY; addr.sin_port = htons( port ); addr.sin_family = AF_INET; server_s = socket( AF_INET, SOCK_STREAM, 0 ); if ( server_s == INVALID_SOCKET ) { error_msg = L"Socket creation failure (" + getWSAErrorString() + L")"; res = -2; goto fail; } set_socket_blocking( server_s, false ); if ( bind( server_s, (struct sockaddr*)&addr, sizeof(addr) ) == SOCKET_ERROR ) { error_msg = L"Socket bind failure (" + getWSAErrorString() + L")"; res = -3; goto fail; } if ( listen( server_s, SOMAXCONN ) == SOCKET_ERROR ) { error_msg = std::wstring( L"Listening at port " ) + longToStr( ntohs( addr.sin_port ) ) + L" failed (" + getWSAErrorString() + L")"; res = -4; goto fail; } // Setup broadcast socket bcast_s = socket( AF_INET, SOCK_DGRAM, 0 ); if ( bcast_s == INVALID_SOCKET ) { error_msg = L"Broadcast socket creation failure (" + getWSAErrorString() + L")"; res = -5; goto fail; } if ( setsockopt( bcast_s, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof( broadcast ) ) < 0 ) { error_msg = L"Broadcast init failure (" + getWSAErrorString() + L")"; res = -6; goto fail; } bcast_addr.sin_family = AF_INET; bcast_addr.sin_port = htons( bcastp ); //bcast_addr.sin_addr.s_addr = INADDR_BROADCAST; bcast_addr.sin_addr.s_addr = inet_addr( bcast_saddr ); //"192.168.0.255" ); goto end; // all is ok fail: cleanup(); end: return res; } // <0 - errors // 0 - pending... // 1 - client has connected // 2 - client normally disconnected // 3 - data was read int simple_server::tick() { const int buf_size = 1024; char buf[ buf_size ]; SOCKADDR_IN addr_c; int addrlen = sizeof( addr_c ); error_msg.clear(); if ( server_s == INVALID_SOCKET ) { error_msg = L"Server socket is not initialized!"; return -1; } if ( bcast_s == INVALID_SOCKET ) { error_msg = L"Broadcast socket is not initialized!"; return -1; } if ( client_s == INVALID_SOCKET ) { // broadcast... sendto( bcast_s, bcast_msg.c_str(), bcast_msg.size(), 0, (sockaddr *)&bcast_addr, sizeof( bcast_addr ) ); // Listen for clients... client_s = accept( server_s, (struct sockaddr*)&addr_c, &addrlen ); if ( client_s != INVALID_SOCKET ) { set_socket_blocking( client_s, false ); client_address[ 0 ] = addr_c.sin_addr.S_un.S_un_b.s_b1; client_address[ 1 ] = addr_c.sin_addr.S_un.S_un_b.s_b2; client_address[ 2 ] = addr_c.sin_addr.S_un.S_un_b.s_b3; client_address[ 3 ] = addr_c.sin_addr.S_un.S_un_b.s_b4; data.clear(); return 1; // client has connected } } if ( client_s != INVALID_SOCKET ) { int read = recv( client_s, buf, buf_size, 0 ); if ( read == SOCKET_ERROR ) { int err = WSAGetLastError(); if ( err != WSAEWOULDBLOCK ) { error_msg = L"Client socket error (" + getWSAErrorString() + L")"; closesocket( client_s ); client_s = INVALID_SOCKET; return -2; } } else { if ( read == 0 ) { closesocket( client_s ); client_s = INVALID_SOCKET; return 2; } for ( int i = 0; i < read; i++ ) { data.push_back( buf[ i ] ); } return 3; // data was read } } return 0; } Немного пояснений - это _однопоточная_ и в этом смысле примитивная и простая в использовании библиотека которая рассылает броадкастом по UDP адрес текущего сервера любому потенциальному клиенту в локальной сети, устанавливает связь с клиентом через серверный сокет и считывает в буфер (vector) data всё что тот ему пошлёт пока соединение не закроется. В связи с этим во первых все сокеты переводятся в неблокирующий режим (сразу возвращают управление, если новый событий нет). А интерфейс к этому объекту выглядит крайне примитивно: 1. вызываем init и если он вернул 0, то: 2. периодически вызываем (вызов неблокирующий, паузы надо выдерживать самому) tick. Результат tick есть руководство к последующему действию: 0 - ничего интересного не произошло (ждём и снова вызываем tick) 1 - присоединился новый клиент (больше одного за заход либка не поддерживает) в этот момент внешний код может взять client_s и послать ему что-либо через send (как и в любой другой момент пока клиент подключен) 2 - клиент отвалился по собственной инициативе, можно прекратить всю деятельность или ждать следующего клиента 3 - клиент прислал новую порцию данных - она добавится к массиву data < 0 - произошла ошибка Такой простой интерфейс позволяет обходить сложность многопоточки и мне вполне подходил.