2013-04-16 3 views
0

Я нахожусь в середине написания веб-сервера, который имеет проблемы с отправкой страниц в браузер. Он правильно отправляет первый файл (этот файл содержит два файла css). но после отправки второго файла браузер перестает запрашивать данные. он всегда пропускает один из файлов css, необходимых для завершения страницы.сокет транзакция не проходит

вот некоторые из операций:

GET/HTTP/1.1 
Host: website.com 
Connection: keep-alive 
Cache-Control: max-age=0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko)    Chrome/26.0.1410.43 Safari/537.31 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: en-US,en;q=0.8 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 

HTTP/1.1 OK 200 
Server: thserver 
Date: Mon Apr 15 17:29:51 2013 
Content-Length: 564 

Data received: GET /main.css HTTP/1.1 
Host: website.com 
Connection: keep-alive 
Accept: text/css,*/*;q=0.1 
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko)  Chrome/26.0.1410.43 Safari/537.31 
Referer: http://website.com/ 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: en-US,en;q=0.8 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 

HTTP/1.1 OK 200 
Server: thserver 
Date: Mon Apr 15 17:29:51 2013 
Content-Length: 386 

Если кто-нибудь знает хороший способ проверки HTTP транзакций, которые помогли бы тоже. Я посмотрел на инструменты разработчика chrome и показал, что он ждет получения последнего файла, но я никогда не получаю запрос на сервере.

Кроме того, я использовал telnet для имитации браузера, и он работал нормально. Вот что я набрал:

GET/
GET /index.css 
GET /main.css 

И каждый раз он отправил файл обратно.

Код продолжает опрос сокета с чтением (2), но продолжает возвращать EAGAIN или EWOULDBLOCK во время прибытия запроса на третий файл.

Вот код для сокета гипергликемии:

const int port_number = 80; 
const int timeout  = 5000000; 
const int wait_time  = 10000; 

PORT_CALL { 

    /* declarations here */ 

    read_client: 

    result = read(socket[ 0 ], &header_buffer[ bytes_read ], BUFFER_SIZE - bytes_read); 

    if(result < 0){ 
     if(errno & (EWOULDBLOCK | EAGAIN)){ 

      if(bytes_read > 0){ 

       bytes_read = 0; 
       read_timeout = 0; 
       goto respond_request; 
      } 
      if(read_timeout < timeout){ 
       read_timeout += wait_time; 
       usleep(wait_time); 
       goto read_client; 
      } 
     } 
     goto exit_thread; 

    } else if(result > -1){ 
     bytes_read += result; 
     goto read_client; 
    } 
    respond_request: 

    /* respond stuff start */ 

    /* respond stuff end */ 

    goto read_client; 

    exit_thread: 

Вот код, который включает в себя создание сокетов

temp->socket_descriptor = socket(AF_INET, SOCK_STREAM, 0); 

temp->server_address.sin_family = AF_INET; 
temp->server_address.sin_addr.s_addr = INADDR_ANY; 
temp->server_address.sin_port = htons(* temp->port_number); 

if(bind(temp->socket_descriptor, 
      (struct sockaddr *) &temp->server_address, 
      sizeof(temp->server_address)) < 0) .. 

listen(temp->socket_descriptor, 10); 

wait_for_client: 

new_socket = accept(temp->socket_descriptor, 
        (struct sockaddr *) &client_address, 
        &address_length); 

Я знаю, я мог бы просить слишком много. Любой, кто знает хороший инструмент отладки, который мог бы мне понять это, я был бы очень признателен за это. Я также считаю это ответом, если кто-то предложит инструмент отладчика, который помог мне понять проблему.

Редактировать: функции записи и чтения теперь находятся в цикле, но проблема все еще происходит.

+1

Вы использовали wirehark или tcpdump для проверки того, что браузер выполняет три запроса? Если это так, вам нужно выяснить, какой из трех запросов ваш сервер «пропускает». Чтобы проверить транзакции, вы должны сравнить полученный файл с исходным файлом. Кроме того, вам нужно проверить, что заголовки ответов - это то, что вы ожидаете от них. – jxh

+0

Я только что скачал tcpdump, все еще изучая, как его использовать. – tay10r

+0

Да, я видел три запроса в дампе tcp. я все еще не уверен, почему я не получаю данные, но теперь я знаю, что должен получать запросы – tay10r

ответ

2

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

Что касается кода, трудно сказать, в чем проблема, так как его не почти SSCCE. У меня есть несколько советов, хотя,

  1. Если вы собираетесь проверить такие вещи, как if(filename), то filename = NULL; после освободить его.
  2. Если вы хотите, чтобы нуль буфера, memset его или цикл по всему размеру. Тест в for(; header_buffer[ i ]; i++) header_buffer[ i ] = 0; выглядит опасным.
  3. Подготовьте для чтения и записи из розетки, возвращающей 0, в дополнение к < 0.
  4. Выполняйте запись в цикле.

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

EDIT, добавленный текст: Код в примере все еще не очень полный (где есть запись fex?), поэтому трудно угадать точную проблему. Однако есть пара довольно фатальных изъянов.

  1. Тестирование ERRNO не должно быть сделано, как это в настоящее время, if(errno & (EWOULDBLOCK | EAGAIN)). В Linux вы можете проверить if (errno == EWOULDBLOCK), так как EAGAIN и EWOULDBLOCK одинаковы. В системе, где они различны, используйте два теста с || между ними. Текущий код возвращает ненулевое значение (в Linux), если errno является fex ECONNRESET.

  2. Теперь код технически охватывает считывание возвращаемого 0, но не как частный случай. Чтение возврата 0 означает, что соединение завершено, и вы больше не должны читать сокет.

Один дикий догадка (связанные с # 2 выше) о том, что может быть проблема в вашем веб-сервере является то, что клиент отключился до получения третьего файла, а сервер сохраняет занят, зацикливание на закрытом сокете.

Я предлагаю просматривать страницы Beejs guide или книгу о системах и программировании сокетов.

+0

спасибо за ответ, я исправил ошибки, о которых вы упоминали, и сделал мой код немного более аккуратным. Я все еще не исправил проблему, но я загрузил Wireshark и теперь использую его. – tay10r

+0

@ Тейлор Я отредактировал свой ответ, чтобы отразить ваши изменения. – thuovila

+0

Я переписал код с нуля, не делая программу многопоточной или динамически связанной (просто чтобы избежать беспорядка). Как вы сказали, я также объяснял закрытые соединения. Он работает сейчас, спасибо за вашу помощь. – tay10r

Смежные вопросы