пример: сделать сервер, для приему текстовых сообщений, чтобы могло коннектиться много клиентов. С Сокетами почти не работал, нашел статью в нете, наваял такой ког (только сетевая часть) Code: while(1){ // Заполняем множестно сокетов fd_set readset; FD_ZERO(&readset); FD_SET(listener, &readset); for(set<int>::iterator it = clients.begin(); it != clients.end(); it++) FD_SET(*it, &readset); timeval timeout; timeout.tv_sec = 30; timeout.tv_usec = 0; // Ждем появления конекта int mx = max(listener, *max_element(clients.begin(), clients.end())); select(mx+1, &readset, NULL, NULL, &timeout); if(select(mx+1, &readset, NULL, NULL, &timeout) <= 0){ cerr<<"select"; exit(3); } if(FD_ISSET(listener, &readset)){ // Есть новый запрос на соединение int sock = accept(listener, NULL, NULL); if(sock < 0){ cerr<<"error accept\n"; exit(3); } fcntl(sock, F_SETFL, O_NONBLOCK); clients.insert(sock); } for(set<int>::iterator it = clients.begin(); it != clients.end(); it++){ if(FD_ISSET(*it, &readset)){ //cout<<"Accept connections...\n"; bytes_read = recvall(*it, XMLstr, 1024, 0); if(bytes_read <= 0){ close(*it); clients.erase(*it); continue; } cout<<XMLstr<<endl; //cout<<"Accept stoped...\n"; XMLstr = ""; } } } в таком случае сервер работает некоторое время (в зависимости от таймаута, и завершает свою работу, а нужно чтобы он висел до тех пор пока его не закроют. Закоментил вот этот код Code: if(select(mx+1, &readset, NULL, NULL, &timeout) <= 0){ cerr<<"select"; exit(3); } теперь сервер весит бесконечно, но так как я не совсем понимаю суть этого кода у меня возникает вопрос, какие из этого могут быть проблемы ?) И как сделать правильней ? И еще одна маленькая проблема, запускаю сервер, запускаю клиент, он отправляет порцию данные, сервер все нормально получает и выводит на экран. Если запустить клиент повторно, то на сервер в конце полученный данных приписывается пару кривых символов, не знаю почему и откуда они. Если сервер перезапустить, то опять в первый раз все нормально, во второй и т.д. приписываются несколько кривых символов Мб проблема где то в логике функции используемой для считывание всего массива данных через сокет Code: int recvall(int s, string &str, int len, int flags){ int total = 0; int n; char buf[1024]; while(1){ n = recv(s, buf, len, flags); if(n <= 0) { break; } str += buf; total += n; } return total; }
Этот код "ждет", пока от клиента станет возможным принимать данные. Т.е. в данном случае прога ждет 30 сек. Если условие не выполнилось, то вызывает exit(3) (по всей видимости выходит я так понимаю). Чтобы сделать ожидание вечным, параметр, где задается timeout, должен быть равен NULL. Т.е. так: Code: if(select(mx+1, &readset, NULL, NULL, NULL) <= 0){ cerr<<"select"; exit(3); } следующий код выполняется даже если еще нет возможности принять данные. по всей видимости ты не очищаешь буфер перед последующими приемами данных. Попробуй очистить str перед заходом в функцию recvall.