0

我在 Windows 应用商店应用程序 ( http://blog.jsolutions.co.uk/?p=492 ) 中使用本地服务器来提供 html 文件。

程序从套接字读取输入:

    StringBuilder inputRequestBuilder = new StringBuilder();

    // Read all the request data.
    // (This is assuming it is all text data of course)
    using (var input = socket.InputStream)
    {
        var data = new Windows.Storage.Streams.Buffer(BUFFER_SIZE);
        uint dataRead = BUFFER_SIZE;

        while (dataRead == BUFFER_SIZE)
        {
            await input.ReadAsync(data, BUFFER_SIZE, InputStreamOptions.Partial);

            var dataArray = data.ToArray();
            var dataString = Encoding.UTF8.GetString(dataArray, 0, dataArray.Length);

            inputRequestBuilder.Append(dataString);
            dataRead = data.Length;
        }
    }

但有时,当用户提交一个 html 表单时,inputRequestBuilder 并没有全部内容,例如:

"POST /LMS/ajax.php?op=commitSCORM HTTP/1.1\r\nAccept: */*\r\nContent-Type: application/x-www-form-urlencoded\r\nReferer: http://localhost:8080/xxxxxxx.htm\r\nAccept-Language: es-ES,es;q=0.8,en-GB;q=0.5,en;q=0.3\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; WebView/1.0)\r\nHost: localhost:8080\r\nContent-Length: 2537\r\nConnection: Keep-Alive\r\nCache-Control: no-cache\r\nCookie: port=8080\r\n\r\n"

内容长度为 2537,但没有内容。所以,我不知道有什么问题。也许 webview 发送两个数据包(http 标头和表单内容)并且......我不知道。

当所有内容都没有准备好时,我再次尝试从套接字读取,但是 VS 抛出:错误 0x80072746 远程主机关闭了连接。

谢谢!

4

2 回答 2

2

你正在传递InputStreamOptions.PartialReadAsync. 这意味着即使线路中有更多数据,ReadAsync也可能返回小于。BUFFER_SIZE

尝试InputStreamOptions.None改用。但这可能不适用于您的情况,因为连接将保持打开状态并且 ReadAsync 将阻塞。您将需要解析Content-Length标头中的值,并在\r\n\r\n.

于 2013-11-08T15:42:20.657 回答
1

随着 Kiewic 的评论,丑陋的脚本有效:

StringBuilder inputRequestBuilder = new StringBuilder();
List<byte> bytes = new List<byte>();
List<byte> last4bytes = new List<byte>();
string request = null;
using (var input = socket.InputStream.AsStreamForRead())
{
    int b;
    while (true)
    {
        try
        {
            b = input.ReadByte();
        }
        catch(Exception e) {
            FileManager.WriteToDebug(e.ToString());
            break;
        }
        bytes.Add((byte)b);
        if (last4bytes.Count < 4)
        {
            last4bytes.Add((byte)b);
        }
        else
        {
            last4bytes.RemoveAt(0);
            last4bytes.Add((byte)b);
            if (last4bytes.ElementAt(0) == 13 && last4bytes.ElementAt(1) == 10
                && last4bytes.ElementAt(2) == 13 && last4bytes.ElementAt(3) == 10)
            {
                //after \r\n\r\n there is the content
                byte[] byteArray = bytes.ToArray();
                request = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
                inputRequestBuilder.Append(request);
                string contentLength = getValueFromHeader("Content-Length", request);
                if (!contentLength.Equals(""))
                {
                    int length = Convert.ToInt32(contentLength);
                    if (length > 0)
                    {
                        byteArray = new byte[length];
                        input.Read(byteArray, 0, length);
                        var dataString = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
                        inputRequestBuilder.Append(dataString);
                    }
                }
                break;
            }
        }
    }
}
request = inputRequestBuilder.ToString();
于 2013-11-12T11:29:57.287 回答