C — Почему мой серверный сокет перестает получать данные, доставленные send() после одного запроса?

#c #sockets #server #request #httpserver

#c #сокеты #сервер #запрос #httpserver

Вопрос:

Я создаю программу на c, которая прослушивает GET и PUT запрашивает и направляет их на httpserver. Проблема в том, что примерно после N запросов (N = количество серверов) httpserver перестает отвечать, потому что он не получает данные от клиента после первого запроса.

Я пересылаю данные, принимая клиентские подключения с использованием accept() , считываю из клиентского сокета и помещаю данные от клиента в буфер, используя recv , пока он не вернет 0. Я отправляю этот буфер на сервер с помощью send() :

 int connect(int from, int to) {
    char buf[BUFFSIZE];
    int n = recv(from, buf, BUFFSIZE-1, 0);
    if (n == 0) { 
       return 0;
    }
    buf[n] = '';
    n = send(to, buf, n, 0);
    if (n == 0) {
        return 0;
    }
    return n;
}
 
 int acceptfd = accept(listenfd,  amp;client_addr, amp;client_addrlen)
connect(acceptfd, serverfd)

 

Мне было интересно, правильно ли я определил конец ввода клиента, но я печатаю вывод send() возвращает точно ожидаемое количество байтов, но сервер его не получает.

Сервер работает отлично каждый раз, когда я делаю запросы к нему независимо. Сервер получает соединения аналогичным образом (я не могу изменить сервер), он принимает клиентские соединения с использованием accept() и считывает из этого сокета с помощью recv. Чтобы уточнить, у меня нет кода сервера, но у меня есть свой собственный, который работает аналогично тому, который я использую для этого проекта, с которым я также тестировал (проблема сохраняется) :

 char buff[BUFF_SIZE   1];
int client_sockd = accept(server_sockd, amp;client_addr, amp;client_addrlen);
int bytes = recv(server_sockd, buff, BUFF_SIZE, 0);

 

Есть ли что-то, о чем я могу неправильно send() понять, или, может быть, буферы? Я попытался использовать флаг O_NONBLOCK, и я использую select() , чтобы определить, из какого сокета читать, поэтому я не знаю, является ли проблема блокировкой.

Комментарии:

1. Сервер их не получает. Что делает сервер вместо того, чтобы получать его?

2. int client_sockd = accept(server_sockd, amp;client_addr, amp;client_addrlen); int bytes = recv(server_sockd, buff, BUFF_SIZE, 0); Это фактический код? recv Сокет должен использовать client_sockd not server_sockd .

3. Вы имеете в виду, что ваш код заблокирован recv ?

4. Вы не можете просто слепо читать с клиента, пока не будет прочитано 0 байт. Это означает, что клиент отключен, поэтому вы не сможете отправить ему ответ. И вы не можете прочитать весь HTTP-запрос за один recv() вызов. Вам нужно вызвать recv() цикл и фактически проанализировать запрос клиента, чтобы узнать, когда он заканчивается. См. Раздел 4.4 RFC 2616 Длина сообщения . Ваш код, как показано, не является допустимым HTTP-приемником, не говоря уже о том, что он не будет работать для клиентов HTTP 1.1, которые используют keep-alives, чтобы оставить соединение открытым между несколькими запросами к одному и тому же серверу

5. @kaylum, нет, на самом деле это не код. У меня нет доступа к коду сервера, только к моему промежуточному коду, но я знаю, что это похоже на то, как это реализовано