我正在使用C#编写TCP客户端和服务器,它们使用手动编写的HTTP请求进行通信。我遇到的问题是使用StreamReader从网络流中读取数据。到目前为止,我尝试了许多方法,但都没有成功。
我从TCP客户端收到的请求有各种形式。对于更新数据库,请求看起来像这样(CRLF是我用来表示
请求格式正确,客户端已正确发送请求 - 我已在可以访问的服务器上进行了测试,并且服务器能够正常响应。
我的问题出现在TCP监听器代码中。为避免发布整个代码,我将只包含有问题的部分(通过调试找到)。
没有任何一种读取方法可行。设置连接超时后,我遇到了IO异常,提示读取时间过长或连接被强制关闭。我关闭了超时设置,但读取需要不确定的时间。
使用
你有什么建议来解决这个问题吗?因为规范中要求使用多个CRLFs的版本。
如果需要额外的信息,我会尽快提供。
我从TCP客户端收到的请求有各种形式。对于更新数据库,请求看起来像这样(CRLF是我用来表示
"\r\n"
字符串的常量):
HTTP 1.0:
"POST /" + name + " HTTP/1.0" + CRLF + "Content-Length: " + length +
CRLF + CRLF + location;
HTTP 1.1:
"POST / HTTP/1.1" + CRLF + hostname + "Content-Length: " + length +
CRLF + CRLF + nameLocString;请求格式正确,客户端已正确发送请求 - 我已在可以访问的服务器上进行了测试,并且服务器能够正常响应。
我的问题出现在TCP监听器代码中。为避免发布整个代码,我将只包含有问题的部分(通过调试找到)。
NetworkStream socketStream = new NetworkStream(connection);
StreamReader sr = new StreamReader(socketStream);
string input = ReadAllLinesWithNull(sr); // reading version 1
string input = ReadAllLinesWithEndOfStream(sr); // reading version 2
string input = ReadAllLinesWithPeek(sr); // reading version 3
string input = sr.ReadToEnd(); // reading version 4
使用的方法包括:
static string ReadAllLinesWithNull(StreamReader sr)
{
string input;
string nextLine;
input = sr.ReadLine();
while ((nextLine = sr.ReadLine()) != null)
{
Console.WriteLine(input);
input += nextLine;
}
sr.Close();
return input;
}
static string ReadAllLinesWithEndOfStream(StreamReader sr)
{
string input = "";
while (!sr.EndOfStream)
{
input += sr.ReadLine();
}
sr.Close();
return input;
}
static string ReadAllLinesWithPeek(StreamReader sr)
{
string input = "";
while (sr.Peek() >= 0)
{
input += sr.ReadLine();
}
sr.Close();
return input;
}
没有任何一种读取方法可行。设置连接超时后,我遇到了IO异常,提示读取时间过长或连接被强制关闭。我关闭了超时设置,但读取需要不确定的时间。
使用
ReadLine()
,我能够找出所有协议版本最终停顿的位置,并发现当两个CRLFs("\r\n\r\n"
)在一起时,流读取器无法处理并会卡住。你有什么建议来解决这个问题吗?因为规范中要求使用多个CRLFs的版本。
如果需要额外的信息,我会尽快提供。
ReadLine
不包含任何终止返回或换行符,因此你发布的内容将返回所有已删除返回和换行符的连接内容。 - Dour High Arch