Pregunta

Saludos, estoy tratando de encontrar una manera de "desvincular" un socket de una combinación particular de IP/puerto.Mi pseudocódigo se ve así:

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.

En este punto, .Net me informa que ya tengo un socket vinculado a 127.0.0.1:4567, lo cual es técnicamente cierto.Pero no importa qué código ponga en el destructor de ClassA, o no importa qué funciones llame en el socket (he probado .Close() y .Disconnect(true)), el socket permanece orgullosamente vinculado a 127.0.0.1:4567.¿Qué debo hacer para poder "desvincular" el socket?


EDITAR:No confío únicamente en la recolección de basura (aunque también probé ese enfoque).Intenté llamar a a.Close() o a.Disconnect() y solo entonces crear una instancia de aa;esto no resuelve el problema.


EDITAR:También intenté implementar IDisposable, pero el código nunca llegó allí sin que yo llamara al método (que era el equivalente de intentos anteriores, ya que el método simplemente intentaría .Close y .Disconnect).Déjame intentar llamar a .Dispose directamente y me comunicaré contigo.


EDITAR (muchas ediciones, disculpas):Implementar IDisposable y llamar a a.Dispose() desde donde 'a' pierde alcance no funciona; mi implementación de Dispose todavía tiene que llamar a .Close o .Disconnect(true) (o .Shutdown(Both)) pero ninguno de ellos se desvincula la toma.

¡Cualquier ayuda sería apreciada!

¿Fue útil?

Solución

(esto es lo que finalmente hizo que todo funcionara para mí)

Asegúrese de que CADA enchufe al que se conecta el enchufe en A tenga

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

establecido al ser iniciado.

Otros consejos

no puede confiar en que el objeto se recolecte como basura en C# (supongo que está usando C#, según el etiquetado) si contiene recursos como estar vinculado al recurso de red como en su ejemplo, o contener algún otro tipo de flujo, un La secuencia de archivos sería un ejemplo común.

debe asegurarse de liberar los recursos que contiene el objeto, para que pueda ser recolectado como basura.de lo contrario, no será recolectado como basura, sino que permanecerá viviendo en algún lugar de la memoria.su ejemplo de pseudocódigo no proporciona que usted esté liberando recursos, simplemente indica que el objeto se recolecta (debe obtener) basura.

El recolector de basura no le garantiza que el socket se cerrará alguna vez.Para un ejemplo completo lea esto Ejemplo de MSDN.

El punto principal es realmente llamar Socket.Close() lo antes posible.Por ejemplo, ClassA podría implementar Desechable y usarlo así:

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

El recolector de basura ejecuta el finalizador del objeto en algún momento indeterminado.Puede implementar la interfaz IDisposable y llamar al método Dispose() antes de que el objeto pierda su alcance, o dejar que la instrucción de uso lo haga por usted.

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

editar:funciona bien para mi

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())
            {
            }
        }
    }
}

La mejor solución es volver a intentar unir el encaje varias veces (2-3).En el primer intento, si falla, descubrí que cerrará correctamente (y permanentemente) el enchufe original.

HTH,

_NUEVO TESTAMENTO

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top