我正在为家庭控制系统构建一个 Windows 8“Metro”客户端,该系统支持将 HTTP 混为一谈作为其协议。我不能使用WebClient
它,因为我需要保持套接字打开并对其执行多个伪 HTTP 操作。
服务器使用的协议非常简单且非常不可变。这是一个古老的软件,永远不会改变。因此,我的客户端代码可以(并且必须)以其独特的方式进行硬编码。
我已经TcpClient
在控制台应用程序中成功构建了它。我现在将它移植到 Win8/Windows Phone 并且现在知道TcpClient
不可用。呃。
我不能使用 ASP.NET Web API 客户端库,因为这HttpClient
似乎也不能让我更好地控制套接字。
所以我被困住了Windows.Networking.Sockets
。下面是我当前的代码(基于TcpClient
。此代码在单独的线程上运行。正如我所说,它在我的 C# 控制台应用程序中运行良好。
private void ReadSubscriptionResponses()
{
// Process the response.
StreamReader rdr = new StreamReader(_subscriptionClient.GetStream());
int contentLength;
int hashCode = 0;
// From here on we will get responses on the stream that
// look like HTTP POST responses.
while (!rdr.EndOfStream) {
var line = rdr.ReadLine();
Debug.WriteLine(line);
if (line.StartsWith("HTTP/1.1 404 ")) {
string error = line.Substring("HTTP/1.1 404 ".Length);
Debug.WriteLine("Error: " + error);
LastStatusCode = "404";
ParseErrorResponse();
continue;
}
LastStatusCode = "200";
if (line.StartsWith("Target-Element: ")) {
string ID = line.Substring("Target-Element: ".Length);
if (!int.TryParse(ID, out hashCode)) {
Debug.WriteLine("Error: Target-Element: is not an integer.");
}
}
// Content-Length: is always the last HTTP header Premise sends
if (!line.StartsWith("Content-Length: ") ||
!int.TryParse(line.Substring("Content-Length: ".Length), out contentLength)) continue;
if (rdr.EndOfStream) continue;
// Read the blank line that always follows Content-Length:
line = rdr.ReadLine();
Debug.WriteLine(line);
if (rdr.EndOfStream) continue;
// Read content
char[] buffer = new char[contentLength];
rdr.ReadBlock(buffer, 0, contentLength);
line = new string(buffer);
// Send line to our caller ...
}
}
这个循环很简单,因为它基于StreamReader.EndOfLine
and StreamReader.ReadLine
。
我希望这Windows.Networking.Sockets.StreamSocket
将提供类似的功能,但没有EndOfStream
或ReadLine
在DataReader
. StreamSocket
有人可以指出我可以在这里使用的使用示例。
我真的想尽可能地保持这段代码的可移植性,这样我就可以在多个平台上运行它。