использование select () для прослушивания нескольких клиентов (TCP) - PullRequest
0 голосов
/ 15 октября 2010

Я разработал (TCP) сервер для прослушивания клиента и взаимодействия с ним. Сейчас я пытаюсь адаптировать этот серверный код для прослушивания нескольких клиентов. Я хочу использовать select, но меня смущают некоторые примеры и объяснения, которые я нашел.

Я читал: http://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr2/select.htm и http://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr2/select.htm оба из которых были мне рекомендованы ..: S

Пример первого сайта кажется менее сложным ... (хотя я до сих пор не знаю, как адаптировать его к моему коду, так как я очень, очень плохо знаком с сетью и т. Д.), Но я беспокоюсь, что упускаю ключевые аспекты из-за сложности примера второго сайта.

Ниже приведен снимок моего серверного кода, когда прослушивает только одного клиента (включен некоторый псевдокод, чтобы минимизировать не столь важные вещи):

int main(int argc, char *argv[])
{
    int    sockfd, newsockfd, portno, clilen;
    char   buffer[3];
    struct sockaddr_in serv_addr, cli_addr;
    int    n;

    if (argc < 2)
    {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
    }

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0){error("ERROR opening socket");}

    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno                    = atoi(argv[1]);
    serv_addr.sin_family      = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port        = htons(portno);


    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        {error("ERROR on binding");}

    listen(sockfd,5);

    clilen = sizeof(cli_addr);
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);

    if (newsockfd < 0){error("ERROR on accept");}


    while (UNTIL END OF FILE)
    {
        <DO SOME FILE READING STUFF>

        n = write(newsockfd, "test/n", 5);

        if (n < 0){error("ERROR writing to socket");}


        bzero(buffer,3);
        n = read(newsockfd,buffer,3);

        if (n < 0){error("ERROR reading from socket");}

        buffer[n] = 0;

        <DO SOME STRING STUFF>

        while(done != 1)
        {
            bzero(buffer,3);
            n = read(newsockfd,buffer,3);

            if (n < 0){error("ERROR reading from socket");}

            buffer[n] = 0;    

            if(strcmp(buffer, "CO"))
            {
                done = 1;
            }
        }

        done = 0;
    }

    <DO STUFF>


    n = write(newsockfd, "DN\n", 2);

    if (n < 0){error("ERROR writing to socket");}

    close(sockfd);
    close(newsockfd);

    return 0;   

}

Какой сайт для select () лучше всего подойдет для того, что я пытаюсь сделать (изменить код сервера для прослушивания нескольких клиентов)? Может ли кто-нибудь объяснить мне select () в более простых терминах? (так как я новичок в этом и во всем ...)

Спасибо!

1 Ответ

7 голосов
/ 15 октября 2010

Вам необходимо обернуть цикл вокруг accept() и следующего кода, чтобы вы могли принять более одного соединения в течение срока действия программы. Затем вам нужно решить, как ваш сервер будет обрабатывать несколько соединений. У вас есть несколько вариантов:

  • Использовать несколько потоков, по одному потоку на клиента.
  • Использовать разветвляющийся сервер, по одному процессу на клиента.
  • Используйте один сервер, который будет использовать select(), чтобы решить, какие файловые дескрипторы готовы.

В первых двух случаях дочерний поток или процесс единодушно работают с одним клиентом; он будет ждать, пока клиент решит, как реагировать на то, что он отправляет, что означает, что другие потоки или процессы получают поворот в ЦП. Существуют различные варианты темы, которые предварительно запускают некоторое количество рабочих потоков или процессов и организуют их для загрузки рабочей нагрузки, но это более сложно.

В последнем случае вы настроите массив файловых дескрипторов, с которыми вы хотите работать select(), и затем передадите копию этого списка в select() (так как он попирает все это). Когда у вас есть работа (потому что select() возвращается), вы выполняете accept() для дескриптора файла, который вы слушаете, если он готов, или вы читаете из уже открытых дескрипторов сокета, если они готовы .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...