Есть ли способ для сокета UDP .net освободить связанный порт, когда сокет закрыт? - PullRequest
2 голосов
/ 26 февраля 2012

Для этого вопроса я использую 64-разрядную версию Windows 7, .net Framework 3.5

Что я действительно хочу знать, это

  1. Есть ли способ отсоединить / освободитьпорт, который был привязан?
  2. Когда я устанавливаю адрес повторного использования сокета, я могу привязаться к порту, но никогда не получаю данные, используя этот адрес / порт?

I 'Я смотрю на то, какие порты связаны, используя netstat -apd udp

Тестовый код, который я использую, приведен ниже, обычно я не закрываю порт после получения одного пакета.

EndPoint endpoint = new IPEndPoint(state.IPAddress, state.Port);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,ProtocolType.Udp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);                    
socket.Bind(endpoint);


ReadStateObject stateObject = new ReadStateObject();
stateObject.socket = socket;
stateObject.Port = state.Port;
stateObject.IPAddress = state.IPAddress;
stateObject.BurstDataReceivedEvent = state.BurstDataReceivedEvent;
stateObject.shutdownRequested = state.StopRequestedEvent;
socket.BeginReceiveFrom(stateObject.buffer,
                        0,
                        stateObject.buffer.Length,
                        SocketFlags.None, // Was 0 which is likely the same enumeration but this is clearer
                        ref endpoint,
                        new AsyncCallback(BurstUdpListener.SocketBeginReceiveAsyncCallback),
                         stateObject);

// wait for read to complete... or the thread to be asked to stop
while (stateObject.readFinished.WaitOne(100, false) == false)
{
    // has this thread been requested to stop? if so, cancel the pending read
    if (state.StopRequestedEvent.WaitOne(1, false) == true)
    {
        stop = true;
        break;
     }
 }

 socket.Shutdown(SocketShutdown.Both);
 socket.Close();
 socket = null;



    private static void SocketBeginReceiveAsyncCallback(IAsyncResult ar)
    {

            if (ar.IsCompleted)
            {
                ReadStateObject state = ar.AsyncState as ReadStateObject;
                if (state != null)
                {
                    if (state.shutdownRequested.WaitOne(1, false))
                        return;
                    EndPoint endpoint = new IPEndPoint(state.IPAddress, state.Port);
                    int bytesReceived = state.socket.EndReceiveFrom(ar, ref endpoint); // for some reason throws error here on changes to settings
                    if (state.BurstDataReceivedEvent != null)
                    {
                        state.BurstDataReceivedEvent(null, new BurstDataReceivedEventArgs(state.buffer, bytesReceived));
                    }
                    state.readFinished.Set();
                }

         }            

 }

1 Ответ

1 голос
/ 27 февраля 2012

Порт должен быть освобожден при вызове close(), поэтому, похоже, либо close() не вызывается, либо не удается.

Удалите вызов shutdown(), поскольку это не совсемприменить к UDP.

Проверьте возврат ошибки close(), чтобы убедиться, что он вызывается и возвращается успешно.

...