Domanda

Saluti, sto cercando di trovare un modo per 'separare' una presa da un particolare combinazione IP/Porta.Il mio pseudocodice assomiglia a questo:

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.

A questo punto, .Net mi informa che ho già una socket associato a 127.0.0.1:4567, che è tecnicamente vero.Ma non importa ciò che il codice l'ho messo in ClassA distruttore, o non importa cosa funzioni di chiamata sul socket (ho provato .Close() e .Scollegare(true)), il socket rimane orgogliosamente legato a 127.0.0.1:4567.Cosa devo fare per essere in grado di 'onu-binding" il socket?


EDIT:Non sto contando esclusivamente sulla raccolta dei rifiuti (anche se ho provato un approccio così).Ho provato a chiamare un.Close() o una.Disconnect() e solo poi istanziare aa;questo non risolve il problema.


EDIT:Ho anche cercato di attuazione IDisposable, ma il codice non ha mai avuto senza la mia chiamata al metodo (che era l'equivalente dei precedenti tentativi, come il metodo sarebbe semplicemente provare .Chiudere e .Scollegare).Mi permetta di provare a chiamare .Disporre direttamente e tornare a voi.


EDIT (un sacco di modifiche, mi scuso):Attuazione IDisposable e di chiamata.Dispose (), da dove e 'un' perde l'ambito non funziona - il mio Smaltire attuazione deve ancora chiamare .Chiudere o .Scollegare(true) o .Arresto(Sia), ma nessuno di quelli che separa la presa.

Qualsiasi aiuto sarebbe apprezzato!

È stato utile?

Soluzione

(questo è quello che finalmente tutto il lavoro per me)

Assicurarsi che la presa che la presa di Un collega ha

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

set dopo essere stato avviato.

Altri suggerimenti

non è possibile fare affidamento su un oggetto in fase di immondizia raccolti in C# (presumo si utilizza c#, basato sul tagging) se sono in possesso di risorse come essere legata alla risorsa di rete come nel tuo esempio, o in possesso di qualche altro tipo di flusso, un flusso di file sarebbe un esempio comune.

è necessario assicurare a rilasciare le risorse che l'oggetto è in possesso, in modo che possa essere di garbage collection.in caso contrario non sarà garbage collection, ma restano vive da qualche parte nella memoria.il pseudocodice esempio, non prevede che si sta facendo le risorse di rilascio, è stato giusto che l'oggetto viene (dovrebbe avere) di garbage collection.

Il garbage collector non garantisce che il socket sarà mai chiuso.Per un esempio completo di leggere questo Esempio MSDN.

Il punto principale è effettivamente Socket.Close() il più presto possibile.Per esempio, ClassA potrebbe implementare IDisposable e di utilizzarlo come questo:

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

Il garbage collector esegue il finalizzatore di un oggetto a un certo tempo indeterminato.Si potrebbe implementare l'interfaccia IDisposable e chiamare il metodo Dispose() prima che l'oggetto perde Ambito di applicazione - o lasciare che l'istruzione using fare per voi.

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

edit:funziona bene per me

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 soluzione migliore è di tentativi di associare la presa un paio di volte (2-3).Al primo tentativo, se non riesce, ho trovato che sarà correttamente (e definitivamente) chiudere il socket originale.

HTH,

_NT

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top