2010-04-16 2 views
1

Как узнать, когда закрыть сокет HTTP-клиента (я имею в виду, что браузер подключается к моему серверу сокетов TCP). Все работает отлично, но в других браузерах, чтобы показать, что сервер отправил, я должен выключить сервер (или вызвать socket.Close()).Как узнать, когда закрыть сокет при работе с HTTP-клиентами?

Он работает нормально, если я позвоню (socket.Close()), но я просто не знаю, когда.? Я не хочу звонить близко в середине запроса, иначе браузер должен перезагрузиться, чтобы снова подключиться к серверу.

+0

Как вы не знаете, когда вы закончили писать ответ? –

+0

LOL true, но безопасно ли закрыться в конце ответа? как насчет ожидающих сообщений? –

ответ

3

Вам необходимо отключить конец разъема, чтобы клиент знал, что данных больше не будет. Вам также нужно прочитать любые ожидающие данные, потому что если вы сразу вызовете Close(), клиент получит сброс (TCP RST).

С кодом выше, как только клиент закрывает свой конец или тайм-аут, который вы определяете, соединение, наконец, будет закрыто на нашем конце.

То, что я давным-давно было это (для Mono's ASP.NET server):

void LingeringClose() 
    { 
     int waited = 0; 

     if (!Connected) 
      return; 

     try { 
      Socket.Shutdown (SocketShutdown.Send); 
      DateTime start = DateTime.UtcNow; 
      while (waited < max_useconds_to_linger) { 
       int nread = 0; 
       try { 
        if (!Socket.Poll (useconds_to_linger, SelectMode.SelectRead)) 
         break; 

        if (buffer == null) 
         buffer = new byte [512]; 

        nread = Socket.Receive (buffer, 0, buffer.Length, 0); 
       } catch { } 

       if (nread == 0) 
        break; 

       waited += (int) (DateTime.UtcNow - start).TotalMilliseconds * 1000; 
      } 
     } catch { 
      // ignore - we don't care, we're closing anyway 
     } 
    } 
+0

Будет ли это работать, даже если у меня есть асинхронный базовый сокет, где я могу передать новую ссылку на сокет, который должен быть выключен, или мне нужно создать список сокетов для проверки и выполнения выключения? –

+0

Я получаю сообщение об ошибке: Попытка сделана в отключенном сокете? ... –

+0

Вышеприведенный код используется в производном от NetworkStream классе и выполняется при явном вызове Close() или GC завершение объекта. Если сокет асинхронен, вам, возможно, придется сделать несколько изменений. – Gonzalo

1

HTTP довольно сложный протокол. RFC 2616 (который вы должен читать, если вы реализуете HTTP-сервер) определяет версию 1.1 и конкретно говорит о подключении в разделе 8.

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