C# - httpWebRequest 流的大小是否有限制?

标签 c# .net http httpwebrequest httpwebresponse

我正在尝试构建一个应用程序,该应用程序使用 httpwebrequests 从自定义网络服务器下载一个小的二进制文件 (20-25 KB)。

这是服务器端代码:

Stream UpdateRequest = context.Request.InputStream;
byte[] UpdateContent = new byte[context.Request.ContentLength64];
UpdateRequest.Read(UpdateContent, 0, UpdateContent.Length);
String remoteVersion = "";
for (int i = 0;i < UpdateContent.Length;i++) { //check if update is necessary
    remoteVersion += (char)UpdateContent[i];
}

byte[] UpdateRequestResponse;

if (remoteVersion == remotePluginVersion) {
    UpdateRequestResponse = new byte[1];
    UpdateRequestResponse[0] = 0; //respond with a single byte set to 0 if no update is required
} else {
    FileInfo info = new FileInfo(Path.Combine(Directory.GetCurrentDirectory(), "remote logs", "PointAwarder.dll"));
    UpdateRequestResponse = File.ReadAllBytes(Path.Combine(Directory.GetCurrentDirectory(), "remote logs", "PointAwarder.dll"));
    //respond with the updated file otherwise
}

//this byte is past the threshold and will not be the same in the version the client recieves
Console.WriteLine("5000th byte: " + UpdateRequestResponse[5000]);

//send the response
context.Response.ContentLength64 = UpdateRequestResponse.Length;
context.Response.OutputStream.Write(UpdateRequestResponse, 0, UpdateRequestResponse.Length);
context.Response.Close();

在此之后,数组 UpdateRequestResponse 包含整个文件并已发送到客户端。

客户端运行这段代码:

//create the request
WebRequest request = WebRequest.Create(url + "pluginUpdate");
request.Method = "POST";
//create a byte array of the current version
byte[] requestContentTemp = version.ToByteArray();
int count = 0;
for (int i = 0; i < requestContentTemp.Length; i++) {
    if (requestContentTemp[i] != 0) {
        count++;
    }
}
byte[] requestContent = new byte[count];
for (int i = 0, j = 0; i < requestContentTemp.Length; i++) {
    if (requestContentTemp[i] != 0) {
        requestContent[j] = requestContentTemp[i];
        j++;
    }
}

//send the current version
request.ContentLength = requestContent.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(requestContent, 0, requestContent.Length);
dataStream.Close();

//get and read the response
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
byte[] responseBytes = new byte[response.ContentLength];
responseStream.Read(responseBytes, 0, (int)response.ContentLength);
responseStream.Close();
response.Close();

//if the response containd a single 0 we are up-to-date, otherwise write the content of the response to file
if (responseBytes[0] != 0 || response.ContentLength > 1) {
    BinaryWriter writer = new BinaryWriter(File.Open(Path.Combine(Directory.GetCurrentDirectory(), "ServerPlugins", "PointAwarder.dll"), FileMode.Create));
    writer.BaseStream.Write(responseBytes, 0, responseBytes.Length);
    writer.Close();
    TShockAPI.Commands.HandleCommand(TSPlayer.Server, "/reload");
}

客户端上的字节数组 responseBytes 应该与服务器上的数组 UpdateRequestResponse 相同,但事实并非如此。在大约 4000 字节后,每个字节都设置为 0,而不是它应该设置的值(responseBytes[3985] 是最后一个非零字节)。

发生这种情况是因为 httpWebRequest 有大小限制吗?我在我的代码中看不到任何可能导致它的错误,并且相同的代码在我只需要传递短数据序列(少于 100 字节)的其他情况下也能正常工作。

MSDN 页面没有提到任何这样的大小限制。

最佳答案

这并不是说它有任何人为限制,这是您尝试执行的操作的 Streaming 性质的副产品。我觉得下面一行是罪犯:

responseStream.Read(responseBytes, 0, (int)response.ContentLength);

我过去遇到过这个问题(使用 TCP 流),它没有读取数组的所有内容,因为它们还没有全部通过网络发送。这就是我要尝试的。

for (int i = 0; i < response.ContentLength; i++)
{
   responseBytes[i] = responseStream.ReadByte();
}

这样,它将确保一直读取到流的末尾。

编辑

usr 基于 BinaryReader 的解决方案效率更高。这是相关的解决方案:

BinaryReader binReader = new BinaryReader(responseStream);
const int bufferSize = 4096;
byte[] responseBytes;
using (MemoryStream ms = new MemoryStream())
{
    byte[] buffer = new byte[bufferSize];
    int count;
    while ((count = binReader.Read(buffer, 0, buffer.Length)) != 0)
        ms.Write(buffer, 0, count);
    responseBytes = ms.ToArray();
}

关于C# - httpWebRequest 流的大小是否有限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38334720/

相关文章:

c# - 如何对 DropDownList 进行排序

c# - 如何将旧式 Windows 图元文件写入文件

C - 处理 HTTP 请求的库

iphone - AFNetworking 自动将请求包装在 JSON 中?

javascript - HTTP GET 生成 Excel 工作簿,用 Express 响应,然后自动下载文件?

c# - 我不能包含 RelayCommands

c# - 使用正则表达式查找两个字符串的完全相等性

c# - 使用单个通用命令处理多个按钮

c# - 具有有效选择的可编辑组合框

c# - 调试失败的 HTTPS WebRequest