代码之家  ›  专栏  ›  技术社区  ›  geowa4

无法将套接字重新绑定到现有IP/端口组合

  •  4
  • geowa4  · 技术社区  · 16 年前

    ClassA a = new ClassA(); //(class A  instantiates socket and binds it to 127.0.0.1:4567) 
    //do something 
    //...much later, a has been garbage-collected away.
    ClassA aa = new ClassA(); //crash here.
    

    此时,.Net通知我已经有一个绑定到127.0.0.1:4567的套接字,这在技术上是正确的。但是,无论我在ClassA的析构函数中放入了什么代码,也不管我在套接字上调用了什么函数(我已经尝试了.Close()和.Disconnect(true)),套接字仍然自豪地绑定到127.0.0.1:4567。如何才能“解除绑定”套接字?


    编辑:我并不完全依赖垃圾收集(尽管我也尝试过这种方法)。我尝试调用a.Close()或a.Disconnect(),然后才实例化aa;这并不能解决问题。


    编辑:我也尝试过实现IDisposable,但如果我不调用该方法,代码就永远无法实现(这与以前的尝试相当,因为该方法只需尝试.Close和.Disconnect)。让我试着打电话给你。直接处理,然后再打给你。


    任何帮助都将不胜感激!

    5 回复  |  直到 16 年前
        1
  •  3
  •   geowa4    16 年前

    (这就是最终让一切为我工作的原因)

    确保中的插座连接到的每个插座都具有

    socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReuseAddress, true);
    

        2
  •  0
  •   zappan    16 年前

    您必须确保释放对象所持有的资源,以便对其进行垃圾收集。否则它就不会被垃圾收集,而是留在内存中的某个地方。您的伪代码示例没有提供您正在进行资源释放,您只是声明对象已(应该)被垃圾回收。

        3
  •  0
  •   David Schmitt    16 年前

    垃圾收集器不能保证套接字将永远关闭。有关完整的示例,请阅读以下内容 MSDN example .

    主要的一点是实际调用 Socket.Close() IDisposable 然后像这样使用它:

    using (ClassA a = new ClassA()) 
    {
        // code goes here
    }
    // 'a' is now disposed and the socket is closed
    
        4
  •  0
  •   VolkerK    16 年前

    垃圾收集器在某个不确定的时间运行对象的终结器。 您可以实现IDisposable接口并在对象失去作用域之前调用Dispose()方法,或者让using语句为您这样做。

    http://msdn.microsoft.com/en-us/library/system.idisposable.aspx http://msdn.microsoft.com/en-us/library/yh598w02.aspx

    using System;
    using System.Net.Sockets;
    using System.Net;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            class ClassA : IDisposable
            {
                protected Socket s;
                public ClassA()
                {
                    s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    s.Bind(new IPEndPoint(IPAddress.Any, 5678));
                }
    
                public void Dispose()
                {
                    s.Close();
                }
            }
    
            static void Main(string[] args)
            {
                using(ClassA a=new ClassA()) {
                }
                using (ClassA b = new ClassA())
                {
                }
            }
        }
    }
    
        5
  •  0
  •   _NT _NT    15 年前

    最好的解决方案是重试绑定套接字几次(2-3次)。在第一次尝试时,如果失败,我发现它将正确(永久)关闭原始套接字。

    嗯,,