Делаю сервер на си с неблокирующими сокетами. Изначально он работает нормально, но в какой то момент происходит ошибка Broken Pipe (в sendall). Не знаю как правильно на нее реагировать? в данном случае я пытаюсь закрыть сокет. в список дескрипторов для select его больше не помещаю и программа работает дальше. Но netstat показывает это соединение как CLOSED и оно не исчезает. Причем изначально сервер может работать стабильно достаточно долго до возникновения первой ошибки потом за ней начинают появляться аналогичные. Всвязи с этим вопросы: 1. Как можно специально вызвать ошибку Broken Pipe чтобы тестить и не ждать пол дня пока она проявится на рабочем сервере? 2. Как закрыть ошибочный сокет полностью чтобы его небыло в netstat? Может у кого есть пример неблокирующего сервера для большого количества соединений, поделитесь плиз) Все примеры, что я нашел очень примитивны без какой либо обработки ошибок( OS: FreeBSD 8.3 Code: // структура клиентов struct deskr_socket { int sd; // сам дескриптор int uid; // уид юзера по базе ... }; struct deskr_socket sockets[MAX_SOCK]; // создание массива клиентов //функция обнуления юзера void zerouser(int no) { sockets[no].sd = 0; sockets[no].uid = 0; ... } void clossing(int number) { //FD_CLR(sockets[number].sd, &readset); //удаляем дескриптор из списка для select //if (shutdown(sockets[number].sd, 2) != 0) printf("shutdown failed: %s\n", strerror( errno )); //закрываем сокет close(sockets[number].sd); zerouser(number); users_count--; printf("clossing %d OK...\n", number); } //Функция отправки данных в сокет (отправляет весь буфер данных) и в случае ошибки будет закрывать сокет int sendall(int s, char *buf, int len, int flags, int no) //no - номер сокета { int total = 0; int n; while(total < len) { n = send(s, buf+total, len-total, MSG_NOSIGNAL); // Вот тут появляется ошибка Broken Pipe if(n == -1) { clossing(no); //В случае ошибки закрываем } total += n; } if (total == len) return 1; else return -1; } int func(int n)//n- номер сокета в массиве с которого пришла мессага { //обработка ... sendall(sockets[n].sd, sendbuf, strlen(sendbuf)+1,0,n); //Отправка ответа } while(1) { FD_ZERO(&readset);//обнуляем множество дескрипторов FD_SET(sock, &readset);// добавляем сокет прослушки в множество дескрипторов //цикл добавления сокетов к множеству дескрипторов проверки сокетов с которых осуществляется чтение for (i=0; i < MAX_SOCK; i++) if (sockets[i].sd > 0 && sockets[i].doclose==0) FD_SET(sockets[i].sd, &readset); timeout.tv_sec = 15; timeout.tv_usec = 0; retval = select(MAX_SOCK+1, &readset, NULL, NULL, &timeout); //получаем список каналов готовых к чтению if (retval) //если есть готовые сокеты { .... .... bytes=recv(sockets[i].sd,buf,BUF_SIZE,0);// читаем if (bytes > 0)//если инфа принята то запускаем функцию обработки мессаг { if (func(i) != 1) //если функция завершилась неправильно то { printf("Error in func()...\n"); clossing(i);//закрываем сокет } }else if (bytes == 0) //если = 0 значит клиент вырубился закрваем сокет { printf("-------------BYTES==========0--------------\n"); if (sockets[i].up) { sockets[i].doclose=1; //ставим метку необходимости закрытия сокета после того как данные сохранятся }else { clossing(i); //запускаем функцию которая заркывает сокет } } else if (bytes < 0) { printf("-------------BYTES<<<<<<<<<<<<0--------------\n"); printf("RECV failed: %s\n", strerror( errno )); //clossing(i); } } } Буду благодарен за любую полезную информацию