You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止Kestrel与其他进程共享端口?

Kestrel端口冲突异常行为排查与解决方案需求

在Windows环境下,Kestrel与ASP.NET Core的端口冲突表现不符合预期,我需要实现:要么让应用正常监听端口,要么检测到冲突时立即记录错误并终止启动,避免出现应用看似运行但无法接收流量的情况。

具体场景:

  • 我有一个用Kestrel搭建的ASP.NET Core站点,同时存在一个通过原生Socket(new Socket(ipPoints[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp))监听80/443端口的控制台程序。
  • 单独运行控制台程序时,执行netstat -Aof | findstr LISTEN | findstr ":80 :443"能看到端口已被监听,浏览器可正常连接。
  • 但在控制台程序运行时启动Kestrel站点,没有触发预期的端口占用错误,站点看似正常启动;再次执行netstat会发现两个进程都在监听同一端口。
  • 反之,启动第二个Kestrel实例时,会正常抛出错误:Unhandled exception. System.IO.IOException: Failed to bind to address https://[::]:443: address already in use.,这才是期望的行为。

实际问题:当其他进程占用端口时,Kestrel虽然显示运行,但完全无法接收流量,已有用户反馈应用"运行正常但无法访问",经查是第三方软件占用端口导致。我需要找到:

  1. 在Kestrel应用内阻止端口共享的方法,让它在检测到冲突时直接抛出错误
  2. 如果无法实现上述需求,也需要了解检测此类端口冲突的最佳实践

示例控制台程序

using System.Net;
using System.Net.Sockets;
using System.Linq;

namespace PortListener
{
    // 参考自Mohsan Saleem的Stack Overflow回答(原来源为MSDN)
    // 略有修改
    class ListenPorts
    {
        private readonly Socket[] _socketConnections;
        private readonly IPEndPoint[] _ipPoints;
    
        internal ListenPorts(IPEndPoint[] ipPoints)
        {
            _ipPoints = ipPoints;
            _socketConnections = new Socket[ipPoints.Length];
        }
    
        public void BeginListening()
        {
            for (var i=0;i<_ipPoints.Length;i++)
            {
                _socketConnections[i] = new Socket(_ipPoints[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                _socketConnections[i].Bind(_ipPoints[i]);
                var thread = new Thread(ListenerThread);
                thread.Start(_socketConnections[i]);
            }
        }
        
        private static void ListenerThread(object? objs)
        {
            var socket = objs as Socket;
            var data = new byte[1024];
    
            IPEndPoint sender;
                
            sender = socket.AddressFamily == AddressFamily.InterNetwork ? 
                new IPEndPoint(IPAddress.Any, 0) : 
                new IPEndPoint(IPAddress.IPv6Any, 0);
    
            EndPoint Remote = sender;
    
            try
            {
                socket.Listen(100);
                var newSocket = socket.Accept();
                newSocket.ReceiveFrom(data, ref Remote);
                newSocket.Close();
                
            }
            catch (SocketException ex)
            {
                Console.WriteLine(ex.Message);
            }
    
            Console.WriteLine($"{socket.LocalEndPoint} -->  {Remote.ToString()}");
        }
    }

    internal static class Program
    {
        private static void Main()
        {
            IPEndPoint[] ipPoints = {
                new (IPAddress.IPv6Any, 443),
                new (IPAddress.IPv6Any, 80),
                new (IPAddress.Any, 443),
                new (IPAddress.Any, 80),
            };
            var portListener = new ListenPorts(ipPoints);
            portListener.BeginListening();
            
            Console.WriteLine($"Now listening on \n{string.Join("\n", ipPoints.Select(x=>x.Address + " " + x.Port))}");
        }
    }
}

示例Kestrel应用

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.UseUrls("https://mymachine.mydomain.com:443;http://mymachine.mydomain.com:80");
            });
}

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

内容的提问来源于stack exchange,提问作者Rob P.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:53:18