The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Сервер с 3мя открытыми портами и select()"
Отправлено socket_select_nonblock, 15-Сен-09 17:23 
Hello, big bro..
Есть проблема..
Делаю сервер с 3 портами, работающими каждый независимо друг от друга...
Использую неблокируюшие сокеты + select. Возникает следующая проблема - после добавления слушающих сокетов в множество селект прекрасно разбирает входящие соединения и разруливает их, нок  примеру если мне необходимо принимать данные от нескольких клиентов (одновременно), после вызова accept только первый клиент посылает данные (на примере эхо-сервера и телнета проверил), а остальные хоть и подключаются, но при вводе строк не получают ответа.. Как только первый клиент отрубается, начинают работать остальные... Как поправить, где пропустил чего?
--
функция принимает 3 порта, функция makeServerSocket принимает порт и возвращает дискриптор слушающего сокета (в ней выполняются последовательно socket, bind, listen).
В этой функции также включен nonblocking mode через fcntl.
Спс :)
P.S. всякие kqueue, epoll и пр. не предлагать плиз взамен этому. Ибо геморрно и разбираться надо :( fork тоже не катит, как и треды...
int startServer(int emulator_port, int controller_port, int system_port)
{
    struct timeval timeout;
    fd_set master_set;
    fd_set working_set;
    char buffer[MAXLINE+1];
    int end_server=0;
    int close_conn;
    int rc,desc_ready;
    int max_sd,new_sd;
    int i,len;
    int emu_sock, contr_sock, sys_sock;
    FD_ZERO(&master_set);
    emu_sock=makeServerSocket(emulator_port);
    FD_SET(emu_sock,&master_set);
    contr_sock=makeServerSocket(controller_port);
    FD_SET(contr_sock,&master_set);
    sys_sock=makeServerSocket(system_port);
    FD_SET(sys_sock,&master_set);
    max_sd=emu_sock+contr_sock+sys_sock;
    do
    {
        memcpy(&working_set,&master_set,sizeof(master_set));
        printf("Waiting on select()...\n");
        rc=select(max_sd+1,&working_set,NULL,NULL,NULL);
        if(rc<0)
        {
            perror("select() failed");
            break;
        }
        if(rc==0)
        {
            printf("select() timed out. End program.\n");
            break;
        }
        desc_ready=rc;
        for(i=0;i<=max_sd && desc_ready>0;++i)
        {
            if(FD_ISSET(i,&working_set))
            {
                desc_ready-=1;
                if(i==emu_sock || i==contr_sock || i==sys_sock)
                {
                    
                    do
                    {
                        if(i==emu_sock)
                        {
                            new_sd=accept(i,NULL,NULL);
                            if(fcntl(i,F_SETFL,O_NONBLOCK)<0)
                            {
                                perror("fcntl failed");
                                return -1;
                            }
                            printf("Emulator socket is readable\n");
                        }
                        else if(i==contr_sock)
                        {
                            new_sd=accept(i,NULL,NULL);
                            if(fcntl(i,F_SETFL,O_NONBLOCK)<0)
                            {
                                perror("fcntl failed");
                                return -1;
                            }
                            printf("Controller socket is readable\n");
                        }
                        else
                        {
                            new_sd=accept(i,NULL,NULL);
                            if(fcntl(i,F_SETFL,O_NONBLOCK)<0)
                            {
                                perror("fcntl failed");
                                return -1;
                            }
                            printf("System socket is readable\n");
                        }
                        if(new_sd<0)
                        {
                            if(errno!=EWOULDBLOCK)
                            {
                                perror("accept() failed");
                                end_server=1;
                            }
                            break;
                        }
                        printf("New incoming connection - %d\n",new_sd);
                        FD_SET(new_sd,&master_set);
                        if(new_sd>max_sd)
                            max_sd=new_sd;
                    } while (new_sd!=-1);
                }
                else
                {
                    printf("Descriptor %d is readable\n",i);
                    close_conn=0;
                    do
                    {
                        rc=recv(i,buffer,sizeof(buffer),0);
                        if(rc<0)
                        {
                            if(errno!=EWOULDBLOCK)
                            {
                                perror("recv() failed");
                                close_conn=1;
                            }
                            break;
                        }
                        if(rc==0)
                        {
                            printf("Connection closed\n");
                            close_conn=1;
                            break;
                        }
                        len=rc;
                        printf("%d bytes received\n",len);
                        rc=send(i,buffer,len,0);
                        if(rc<0)
                        {
                            perror("send() failed");
                            close_conn=1;
                            break;
                        }
                    } while (1);
                    if(close_conn)
                    {
                        close(i);
                        FD_CLR(i,&master_set);
                        if(i==max_sd)
                        {
                            while(FD_ISSET(max_sd,&master_set) == 0)
                                max_sd-=1;
                        }
                    }
                }
            }
        }
    } while(!end_server);
    
    for(i=0;i<=max_sd;++i)
    {
        if(FD_ISSET(i,&master_set))
            close(i);
    }
    
    return 0;
}
 

Ваше сообщение
Имя*:
EMail:
Для отправки новых сообщений в текущей нити на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру