2015-08-30 41 views
2

首先,我正在開發Windows通用應用程序項目。我使用StreamSocketListener創建了一個簡單的tcp偵聽器。數據來自連接到本地網絡的設備。這些設備隨機發送Http和Http/Xml數據包。C#Http服務器使用StreamSocketListener,選項「InputStreamOptions.Partial」返回數據不完整

我所創建的套接字監聽如下:

StreamSocketListener listener = new StreamSocketListener(); 

public async void HttpServer() 
{ 
    listener.ConnectionReceived += (s, e) => ProcessRequestAsync(e.Socket); 
    HostName hostName = new HostName("192.168.0.150"); 
    NetworkAdapter thisAdapter = hostName.IPInformation.NetworkAdapter; 
    await listener.BindServiceNameAsync("5400", SocketProtectionLevel.PlainSocket, thisAdapter); 
} 

而當數據是可用的,這是回調函數:

private const uint BufferSize = 12000; 

private async void ProcessRequestAsync(StreamSocket socket) 
{ 

    StringBuilder request = new StringBuilder(); 

    using (IInputStream input = socket.InputStream) 
    {    
     byte[] data = new byte[BufferSize]; 
     IBuffer buffer = data.AsBuffer(); 
     uint dataRead = BufferSize; 
     while (dataRead == BufferSize) 
     { 
      await input.ReadAsync(buffer, BufferSize, InputStreamOptions.None); 
      request.Append(Encoding.UTF8.GetString(data, 0, (Int32)buffer.Length)); 
      dataRead = buffer.Length; 
     } 

    String message = request.ToString(); 

    ExampleTextLabel.Text = message; 

    .... 

} 

這裏的問題是:

我已經設置了BufferSize = 12000.這是因爲,到目前爲止,我收到的最大數據長度都低於11500.內容的長度是i n中的HTML頭(內容長度),但我不知道如何前行讀頭:

await input.ReadAsync(buffer, BufferSize, InputStreamOptions.None); 

當我使用的選項InputStreamOptions.None,我收到的消息是由一個數據包延遲。因爲我用

ExampleTextLabel.Text = message; 

當數據包到達2,在ExampleTextLabel表示從分組1.消息我知道這一點:換句話說,當設備發出數據包1,它不把它寫在下面的文本標籤Wireshark觀察傳入的數據包。

另一方面,如果我使用選項InputStreamOptions.Partial,沒有延遲。我收到Wireshark中顯示的數據包。然而,這個解決方案的問題是大部分時間數據包被破壞(不完整)。

有人可以解釋我這裏的問題,如果有任何解決方案?

謝謝!

+0

嗨,你有沒有成功的StreamSocketListener創建通用的http服務器?我正在開發通用應用程序,我也需要http服務器。我們可以開始github項目。 – ADOConnection

+0

是的我的HTTP服務器按預期工作,但我沒有使它通用。看起來好像沒有太多的例子,所以我會把它變成通用的並且分享它。 – Ege

回答

1

回答我的問題,

InputStreamOptions.Partial是異步讀取,當一個或多個字節可用操作完成。

這意味着它有時會結束讀操作而不完成數據包。我做了以下修改上面的代碼,得到它的工作(而不是實際的代碼,只是評價給出出主意):

while (allDataRead) 
{ 
    await input.ReadAsync(buffer, BufferSize, InputStreamOptions.None); 
    request.Append(Encoding.UTF8.GetString(data, 0, (Int32)buffer.Length)); 
    dataRead = buffer.Length; 

    //make sure the data read contains the html header, otherwise loop again 
    //until you can extract the HTML header. 
    //Get the content length from the HTTP header. 

    //If the buffer size does not match the content length + html header length, 
    //then loop again to get the remaining packets until the buffer length 
    //matches the content length + html header length 

    //If the content length matches the buffer length then you have received the packet completely. 
    //allDataRead=true to exit the loop. 

} 
相關問題