webapi.owinSelfHost:文件下载速度慢

问题描述 投票:0回答:1

使用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)

可以告诉我如何解决这个问题吗?

c# asp.net .net owin webapi
1个回答
0
投票
response.Content = new System.Net.Http.StreamContent(_value);

更改为

response.Content = new ByteArrayContent(_value.GetBuffer(), 0, (int)_value.Length)

将会解决问题

© www.soinside.com 2019 - 2024. All rights reserved.