Отправка при получении в С - PullRequest
3 голосов
/ 31 мая 2010

Я сделал кусок кода в том, что на моем сервере в виде нескольких потоков

Проблема в том, что он не отправляет данные во время приема на другом сокете.

поэтому, если я отправляю что-то от клиента 1 к клиенту 2, client2 получает только, если он сам что-то отправляет (выпрыгивает из функции recv) .. как я могу решить это?

 /* Thread*/
while (! stop_received) {
        nr_bytes_recv = recv(s, buffer, BUFFSIZE, 0);

        if(strncmp(buffer, "SEND", 4) == 0) {
            char *message = "Text asads \n";
            rv = send(users[0].s, message, strlen(message), 0);
            rv = send(users[1].s, message, strlen(message), 0);
            if (rv < 0) {
                perror("Error sending");
                exit(EXIT_FAILURE);
            }           
        }else{
            char *message = "Unknown command \n";
            rv = send(s, message, strlen(message), 0);
            if (rv < 0) {
                perror("Error sending");
                exit(EXIT_FAILURE);
            }
        }
}

Ответы [ 6 ]

7 голосов
/ 31 мая 2010

Чтобы быть более конкретным, есть несколько типов ввода / вывода. То, что вы делаете в настоящее время, называется блокировкой ввода / вывода. В целом это означает, что при вызове send или recv операция будет «блокироваться» до ее завершения.

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

Вы можете посмотреть пример программы здесь на Выберите учебник . Полный исходный код находится внизу страницы.

Как уже отмечали другие, вы можете использовать темы.

2 голосов
/ 31 мая 2010

Ваш код заблокируется при вызове recv(). Либо напишите многопоточное приложение, либо изучите использование функции select () .

1 голос
/ 31 мая 2010

Я заметил, что вы используете perror() (функция ошибок POSIX), что заставляет меня думать, что вы используете операционную систему POSIX, что заставляет меня подозревать ее GNU / Linux.

select() является переносимым, poll() ориентирован на POSIX, а epoll() ориентирован на Linux. Если вы используете GNU / Linux, я настоятельно рекомендую избегать select() и использовать:

  • poll() если вы опрашиваете только несколько десятков файловых дескрипторов
  • epoll(), если вам нужно масштабировать до тысяч подключений, и это доступно.

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

Если требуется переносимость, посмотрите, существует ли poll() или epoll() во время конфигурации сборки, и используйте либо в пользу select().

Заметьте, epoll() не появлялся до Linux 2.5 (что-то), поэтому лучше всего использовать оба.

1 голос
/ 31 мая 2010

Поместите отправку и получение в отдельных темах.

0 голосов
/ 31 мая 2010

Существует два способа достижения желаемой цели:

1.) Реализовать отправляющий и принимающий коды в разных потоках.но будут некоторые проблемы, например, увеличение числа клиентов может привести к проблемам при работе с кодом.также будет некоторая проблема параллелизма (как упомянуто pcent).Вы не можете использовать блокирующие сокеты, но я советую этого не делать, так как я надеюсь, что вам не нужен процессор.

2.) Другой способ - использовать функцию select (), которая позволит вам контролироватьнесколько розеток разных типов одновременно.Более подробное описание "select ()" вы можете найти в Google.:)

0 голосов
/ 31 мая 2010

Вы должны разделить код на два потока: один передатчик и один приемник.

Примерно так:

 /* 1st Thread*/
while (! stop_received) {
        nr_bytes_recv = recv(s, buffer, BUFFSIZE, 0);
}


 /* 2nd Thread*/
while (! stop_received) {
        if(strncmp(buffer, "SEND", 4) == 0) {
            char *message = "Text asads \n";
            rv = send(users[0].s, message, strlen(message), 0);
            rv = send(users[1].s, message, strlen(message), 0);
            if (rv < 0) {
                perror("Error sending");
                exit(EXIT_FAILURE);
            }           
        }else{
            char *message = "Unknown command \n";
            rv = send(s, message, strlen(message), 0);
            if (rv < 0) {
                perror("Error sending");
                exit(EXIT_FAILURE);
            }
        }
}

Параллельность вызовет некоторые проблемы, такие как доступ к переменной buffer.

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