问候,我正试图找到一种方法来解除特定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。我该怎么做才能“解除”套接字?
任何帮助将不胜感激!
答案 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.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()) { } } } }
答案 4 :(得分:0)
最好的解决方案是重试几次绑定套接字(2-3)。在第一次尝试时,如果失败,我发现它将正确(并永久)关闭原始套接字。
HTH,
_NT