使用webapi.owinSelfHost库创建Web服务器时,通过服务器从其他计算机下载文件的速度非常慢。这是为什么? 我的网络是10GE,正常传输速度可以达到1.4G/s。我自己用.net 6写了一个webapi程序和一个客户端。测试速度也可以达到1.4G/s。 下面是运行服务器的代码
public class RestServer
{
internal static List<Type> Controllers = new();
public static void Register<T>() where T : ApiController
{
if (Controllers.IndexOf(typeof(T)) == -1)
{
Controllers.Add(typeof(T));
}
}
public static void UnRegister<T>() where T : ApiController
{
Controllers.Remove(typeof(T));
}
public static void Run(string hostName = "localhost", int port = 37701)
{
if (hostName.StartsWith("http"))
{
WebApp.Start<RestServer>(hostName);
}
else
{
WebApp.Start<RestServer>($"http://{hostName}:{port}");
}
}
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Services.Replace(typeof(IHttpControllerTypeResolver), new HttpControllerTypeResolverWithRegister());
appBuilder.UseWebApi(config);
}
}
public class BigDataController : IHttpActionResult
{
public override Task<IRestResult> Get(string id = null)
{
return Task.Run(() =>
{
try
{
Program.bigfile.Position = 0;
return BuildStream(Program.bigfile);
}
catch (Exception ex)
{
Console.WriteLine(ex.GetBaseException().ToString());
throw;
}
});
}
}
class StreamResult : IHttpActionResult
{
Stream _value;
HttpRequestMessage _request;
public StreamResult(Stream value, HttpRequestMessage request)
{
_value = value;
_request = request;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage();
response.RequestMessage = _request;
if (_value is null)
{
response.StatusCode = System.Net.HttpStatusCode.NoContent;
}
else
{
_value.Position = 0;
response.Content = new System.Net.Http.StreamContent(_value);
response.Content.Headers.ContentType=new MediaTypeHeaderValue("application/octet-stream");
}
//response.Headers.Add("Content-Type", "application/octet-stream");
return Task.FromResult(response);
}
}
http 响应标头和正文与其他 webapi 应用程序相同 owinSelfhost 应用程序的响应标头
Hypertext Transfer Protocol
HTTP/1.1 200 OK\r\n
Content-Length: 165955581\r\n
Content-Type: application/octet-stream\r\n
Server: Microsoft-HTTPAPI/2.0\r\n
Date: Sat, 16 Sep 2023 08:58:37 GMT\r\n
\r\n
[HTTP response 1/1]
[Time since request: 20.571075000 seconds]
[Request in frame: 98824]
[Request URI: http://10.0.10.100:37701/api/BigData/122]
File Data: 165955581 bytes
webapi应用程序的响应头
Hypertext Transfer Protocol
HTTP/1.1 200 OK\r\n
Content-Length: 129549096\r\n
Content-Type: application/octet-stream\r\n
Date: Sat, 16 Sep 2023 08:57:32 GMT\r\n
Server: Kestrel\r\n
Content-Disposition: attachment; filename=bigdata; filename*=UTF-8''bigdata\r\n
\r\n
[HTTP response 1/1]
[Time since request: 0.533893000 seconds]
[Request in frame: 208]
[Request URI: http://10.0.10.100:5156/w]
File Data: 129549096 bytes
Tcp窗口大小和缩放因子相同,两者的TCP报文段数据不同,如下 owinSelfHost 应用程序
Transmission Control Protocol, Src Port: 37701, Dst Port: 49706, Seq: 165955151, Ack: 129, Len: 585
Source Port: 37701
Destination Port: 49706
[Stream index: 3]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 585]
Sequence Number: 165955151 (relative sequence number)
Sequence Number (raw): 2754326255
[Next Sequence Number: 165955736 (relative sequence number)]
Acknowledgment Number: 129 (relative ack number)
Acknowledgment number (raw): 3724955552
0101 .... = Header Length: 20 bytes (5)
Flags: 0x018 (PSH, ACK)
Window: 8212
[Calculated window size: 2102272]
[Window size scaling factor: 256]
Checksum: 0x2b2c [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]
TCP payload (585 bytes)
TCP segment data (585 bytes)
webapi 应用程序
Transmission Control Protocol, Src Port: 5156, Dst Port: 49705, Seq: 129548192, Ack: 44, Len: 1122
Source Port: 5156
Destination Port: 49705
[Stream index: 1]
[Conversation completeness: Complete, WITH_DATA (47)]
[TCP Segment Len: 1122]
Sequence Number: 129548192 (relative sequence number)
Sequence Number (raw): 1706970176
[Next Sequence Number: 129549314 (relative sequence number)]
Acknowledgment Number: 44 (relative ack number)
Acknowledgment number (raw): 3207951358
0101 .... = Header Length: 20 bytes (5)
Flags: 0x018 (PSH, ACK)
Window: 8212
[Calculated window size: 2102272]
[Window size scaling factor: 256]
Checksum: 0x2d45 [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]
TCP payload (1122 bytes)
TCP segment data (1122 bytes)
可以告诉我如何解决这个问题吗?
response.Content = new System.Net.Http.StreamContent(_value);
更改为
response.Content = new ByteArrayContent(_value.GetBuffer(), 0, (int)_value.Length)
将会解决问题