我正在为家庭控制系统构建一个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
和StreamReader.ReadLine
。
我希望Windows.Networking.Sockets.StreamSocket
提供类似的功能,但EndOfStream
中没有ReadLine
或DataReader
。有人能指出我使用StreamSocket
的例子,我可以放在这里。
我真的希望尽可能保持这段代码的可移植性,以便我可以在多个平台上运行它。