Очередь recv в соединении с сервером - PullRequest
0 голосов
/ 20 декабря 2011

Ситуация : я создаю серверный демон в c, который принимает множество одновременных подключений, и клиенты будут отправлять данные на сервер. В настоящее время каждое клиентское соединение создается в новом потоке.

Проблема : если клиент отправляет множество строк контента очень быстро (например, 10 строк данных менее чем за секунду), сервер увидит первые две строки, но не остальные.

Вопрос : Как я могу «поставить в очередь» данные, поступающие от клиентов (команда recv в c)? Это то, что нужно select или poll? По сути, я хочу убедиться, что любой клиент может очень быстро отправлять большие объемы данных, не беспокоясь о том, что какой-либо контент будет удален. Как этого достичь?

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

//this function handles the threads
void *ThreadedFunction(void *arg) {
    // do some stuff, like: pull vars out of mystruct
    int nbytes;
    char buf[256];
    while(1) {
        if((nbytes=recv(conid, buf, sizeof buf, 0)) <= 0) {
            //handle break in connection
        } else {
            //for this example, just print out data from client to make my point
            buf[nbytes] = 0;
            printf("%s\n",buf);
        }
    }
}

//main just sets up the connections and creates threads
int main(int argc. char *argv[])
{
    // bind(), listen(), etc... blah blah blah

    while(1) {
        conid = accept(...); //get a connection
        // ... build mystruct to pass vars to threaded function ...
        pthread_t p;
        pthread_create(&p,NULL,ThreadedFunction,&mystruct); //create new thread
    }
}

1 Ответ

0 голосов
/ 20 декабря 2011

Вам не нужно «ставить в очередь» данные, поступающие от клиентов.Потому что TCP сделает это за вас.Управление потоком данных TCP даже замедляет работу клиентов, если сервер слишком медленный, чтобы освободить место для приемного буфера TCP.

Таким образом, возможно, имеется ошибка в коде сервера или клиента.Возможно, клиент отправляет '\ 0' в конце каждой строки.В этом случае следующий код не будет печатать все строки:

if((nbytes=recv(conid, buf, sizeof buf, 0)) <= 0) {
    //handle break in connection
} else {
    //for this example, just print out data from client to make my point
    buf[nbytes] = 0;
    printf("%s\n",buf);
}

Можно даже ожидать, что 2-я строка - это последняя строка, которую вы видите, если клиент отправляет '\ 0' в конце каждогоline.

Например:

Если клиент отправляет следующие строки:

"abc\n\0"
"def\n\0"
"ghi\n\0"

Обычно TCP отправляет их, используя два пакета, которые содержат следующее:

"abc\n\0"
"def\n\0ghi\n\0"

Серверу обычно требуется 2 вызова recv для получения входящих данных.Таким образом, ваш сервер будет использовать 2 вызова для печати:

printf("%s\n", "abc\n\0\0");
printf("%s\n", "def\n\0ghi\n\0\0");

И результат будет:

abc
def
...