2016-03-25 10 views
0

Ситуация

Мы используем следующий код для приема входящих HTTP-запросов.Как долго мы должны ждать проверки доступных данных после приема соединения?

var localEndPoint = new IPEndPoint(IPAddress.Any, Port); 

var serverSocket = new Socket(
    AddressFamily.InterNetwork, 
    SocketType.Stream, 
    ProtocolType.Tcp); 

serverSocket.Bind(localEndPoint); 
serverSocket.Listen(backlog: 25); 

while (true) 
{ 
    using (var clientSocket = serverSocket.Accept()) 
    { 
     if (clientSocket.Available > 0) 
     { 
      var builder = new StringBuilder(); 

      while (clientSocket.Available > 0) 
      { 
       var currentBytes = new byte[clientSocket.Available]; 
       var bytesReceived = clientSocket.Receive(currentBytes); 

       var currentBytesString = 
        new string(Encoding.UTF8.GetChars(currentBytes)); 

       builder.Append(currentBytesString); 
      } 
     } 
    } 
} 

Проблема

Иногда clientSocket.Available равна нулю, даже если соединение имеет данные. Решение, которое мы реализовали, состоит в том, чтобы дождаться, когда вы примете соединение, прежде чем мы проверим, доступны ли данные. Мы делаем это следующим образом:

var start = DateTime.Now; 
var duration = new TimeSpan(0); 
while (clientSocket.Available <= 0 || duration.Milliseconds < 1000) 
{ 
    duration = DateTime.Now - start; 
    Thread.Sleep(100); 
} 

Вопрос

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

Рабочий раствор

Спасибо szym за вдохновение для этого подхода. Сейчас он работает.

while (true) 
{ 
    using (var clientSocket = serverSocket.Accept()) 
    { 
     var builder = new StringBuilder(); 

     do 
     { 
      var currentBytes = new byte[50]; 
      var bytesReceived = clientSocket.Receive(currentBytes); 

      var currentBytesString = 
       new string(Encoding.UTF8.GetChars(currentBytes)); 

      builder.Append(currentBytesString); 
     } 
     while (clientSocket.Available > 0); 
    } 
} 
+1

Почему бы не просто позвонить Читать и блокировать ли данные до тех пор, пока данные не будут доступны? –

+0

Не знаю. Что означает «Доступно» в этом случае? –

ответ

1

Как правило, вам, возможно, придется подождать некоторое время (думаю дрянные сети с огромными временами спускоподъемных), таймаут по умолчанию на некоторых платформах составляет 20 секунд!

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

Цитирует documentation (курсив мой):

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

+0

Где этот метод 'Read', о котором вы говорите? –

+0

Документы не перечисляют такой метод. https://msdn.microsoft.com/en-us/library/system.net.sockets.socket%28v=vs.110%29.aspx –

+1

Извините, обновлено с помощью 'Receive', которое является именем в .NET-сокетах. – szym

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

  • Нет связанных вопросов^_^