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

时间:2008-09-07 11:56:50

标签: c# .net networking sockets

问候,我正试图找到一种方法来解除特定IP /端口组合中的套接字。我的伪代码看起来像这样:

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),代码永远不会到达那里。让我试着直接打电话。直接告诉你。


编辑(很多编辑,道歉):实现IDisposable并从'a'失去范围调用a.Dispose()不起作用 - 我的Dispose实现仍然需要调用.Close或.Disconnect(true)(或.Shutdown(Both))但没有一个解开套接字。

任何帮助将不胜感激!

5 个答案:

答案 0 :(得分:3)

(这就是最终让我感到满意的一切)

确保A中的套接字连接的每个套接字都有

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

立即启动。

答案 1 :(得分:0)

你不能依赖于在C#中收集垃圾的对象(我假设你正在使用c#,基于标记),如果它拥有像你的例子一样绑定到网络资源的资源,或者持有其他类型的流,文件流将是一个常见的例子。

您必须确保释放对象所持有的资源,以便可以对其进行垃圾回收。否则它不会被垃圾收集,但仍然存在于记忆中的某个地方。你的伪代码示例没有提供你正在进行的资源释放,你只是声明对象得到(应该得到)垃圾收集。

答案 2 :(得分:0)

垃圾收集器不保证您将永久关闭套接字。有关完整示例,请阅读此MSDN example

重点是尽快打电话给Socket.Close()。例如,ClassA可以实现IDisposable并像这样使用它:

using (ClassA a = new ClassA()) 
{
    // code goes here
}
// 'a' is now disposed and the socket is closed

答案 3 :(得分:0)

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

请参阅http://msdn.microsoft.com/en-us/library/system.idisposable.aspxhttp://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())
            {
            }
        }
    }
}

答案 4 :(得分:0)

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

HTH,

_NT

相关问题