2012-07-03 3 views
1

Я пытался создать приложение метро, ​​но есть проблема: StreamSocket действительно не делать то, что я хочу делать (я думаю)NetworkStream Equivelant

Вот отрывок из моего кода .Net, который работает :

 try 
     { 
      TCP = new TcpClient(server, port); 
      Stream = TCP.GetStream(); 
      Read = new StreamReader(Stream); 
      Write = new StreamWriter(Stream); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("Error connecting to " + server + ": " + e); 
      return; 
     } 

     // Identify 
     Write.WriteLine("LOGIN " + Username); 
     Write.Flush(); 

     while (Connected) 
     { 
      try 
      { 
       if ((line = Read.ReadLine()) != null && Connected) 

Я не могу StreamSocket работать ... это требует, чтобы узнать длину строки, которая приходит и я не знаю, что это будет - она ​​меняется. Есть ли способ сделать это, что будет работать?

Это то, что у меня есть, но он не работает:

 try 
     { 
      // Connect to the server (in our case the listener we created in previous step). 
      await Socket.ConnectAsync(new HostName("example.com"), "1111"); 
     } 
     catch (Exception exception) 
     { 
      // If this is an unknown status it means that the error is fatal and retry will likely fail. 
      if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) 
      { 
       throw; 
      } 
     } 

     // Create a DataWriter if we did not create one yet. Otherwise use one that is already cached. 
     Writer = new DataWriter(Socket.OutputStream); 
     Listener = new DataReader(Socket.InputStream); 

     Debug.WriteLine(Socket.Information.RemoteAddress.CanonicalName); //Check if IP is correct 

     SendRaw("LOGIN " + Nickname); 

     string line = ""; 
     Connected = true; 
     while (Connected) 
     { 
      if (Listener.UnconsumedBufferLength != 0) 
      { 
       line = Listener.ReadString(Listener.UnconsumedBufferLength); 
       Debug.WriteLine(line); 
      } 
     } 
    } 

    async public void SendRaw(string str) 
    { 
     Writer.WriteString(str); 

     // Write the locally buffered data to the network. 
     try 
     { 
      await Writer.StoreAsync(); 
     } 
     catch (Exception exception) 
     { 
      // If this is an unknown status it means that the error if fatal and retry will likely fail. 
      if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) 
      { 
       throw; 
      } 
     } 
    } 

Любая помощь будет оценен по достоинству!

+0

Какая у вас тестовая среда? Ссылка [Ссылка MSDN] (http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.streams.datareader.unconsumedbufferlength (v = VS.85) .aspx # Y200) гласит, что вы требуется, по крайней мере, предварительный просмотр Windows 8. –

+0

Я использую Windows 8 RP. Проблема в том, что я не получаю никакого ввода с помощью приложения Metro, пока приложение .Net отлично работает –

+0

Вы видите, что такое значение 'Listener.UnconsumedBufferLength'? –

ответ

2

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

Вторая вещь вторая: класс DataReader должен прочитать несколько байтов в своем внутреннем буфере, прежде чем он сможет их интерпретировать. Вы читаете этот буфер, вызывая LoadAsync.

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

Update:

Набор InputStreamOptions для Partial; вы можете вызвать LoadAsync с произвольным большим размером буфера (например, 1024). После получения данных звоните ReadString(UnconsumedBufferLength). Каждый раз, когда вы это делаете, вы можете получить часть строки, строки или больше строки. Таким образом, вам нужно будет создать string, а затем Split на \n, сохраняя любую частичную линию в конце в следующий раз через цикл.

+0

Я не проектировал протокол, это вроде как IRC –

+0

Итак, мне нужно загрузить LoadAsync.Проблема в том, что я не знаю, насколько большие пакеты будут - они варьируются от 3 до sizeof (string) ... Есть ли способ загрузить буфер любого размера? Сделав 119 (первый пакет), я смог получить ответ первого пакета ... –

+0

См. Обновленный ответ. –