背景

今天在处理一个c#应用崩溃的问题的时候,发现这样一行调试信息。

“System.Net.Sockets.SocketException”类型的未经处理的异常在 System.dll 中发生 
以一种访问权限不允许的方式做了一个访问套接字的尝试。

一、分析

  1. 出现这样的错误信息,我一直以为是我代码里的问题。(譬如说访问已经close的套接字)
  2. 后来查了一下,大家都说是换个端口。
  3. 换个端口,果然不崩溃了。但是我的程序却必须使用那个端口。
  4. 只能想点法子

二、确认问题所在

  1. 开始—->运行—->cmd,调出命令窗口
  2. 输入命令:netstat -ano,列出所有端口的情况。在列表中我们观察被占用的端口,我被占用的事3702
  3. 查看对应的进程PID,输入命令:netstat -aon|findstr “3702”,得到进程PID是 488
  4. 打开任务管理器,在进程PID那一列查看488对应的进程是哪个
  5. 发现果然是端口被某些系统服务占用了。

三、处理办法

  1. 第一种
    这种方法是是像360那样子,把占用端口的程序杀掉。(这样子做会给用户带来麻烦,而且即使杀死了,用户去检查和处理起来反倒更麻烦)
  2. 第二种
    这种方法是,提醒用户去处理这个问题,不帮用户杀掉占用端口的程序。
    以我的应用为例,我可以在用户打开我的程序的时候,提醒他端口被占用,然后换一个端口运行。但是,端口换掉可能会导致某些信息接收不到,需要把这个后果告诉用户,让用户自行处理。每次用户打开我的应用的时候,都检查一下,发现被占了,就提醒一次。直到用户解决完电脑或者设备上的冲突了,就不再显示这个问题了。

四、代码

下面贴一下检测端口占用的c#代码吧。
1. 第一种是利用c#的类库检测

#region 端口检测
            IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
            IPEndPoint[] udpEndPoints = properties.GetActiveUdpListeners();
            if (udpEndPoints.Where(pp=>pp.Port == 3702).Count()>0)
            {
                MessageBox.Show(udpEndPoints.Where(pp => pp.Port == 3702).First().Address.ToString());
            }
#endregion
  1. 第二种是利用netstat命令工具检测
#region 检测端口是否被占用
            Process p = new Process();
            p.StartInfo = new ProcessStartInfo("netstat", "-a");
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.StartInfo.RedirectStandardOutput = true;
            p.Start();
            string result = p.StandardOutput.ReadToEnd().ToLower();
            if (result.IndexOf(Environment.MachineName.ToLower() + ":3702") >= 0)
            {
                MessageBox.Show("端口被占用");
            }
            else
            {
                MessageBox.Show("ok");
            }
#endregion





http://xzh.i3geek.com

爱唠叨的老鱼

爱唠叨的老鱼

技术经理,个人站长,创业者

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据