【问题标题】:Is there a way to for UDP .net socket to release a bound port when the socket is closed?有没有办法让 UDP .net 套接字在套接字关闭时释放绑定端口?
【发布时间】:2012-02-25 22:41:59
【问题描述】:

对于这个问题,我正在运行 windows 7 64 位,.net framework 3.5

我真正想知道的是

  1. 有没有办法解除绑定/释放已绑定的端口?
  2. 当我设置 socketoption 重用地址时,我能够绑定到端口,但我从未使用该地址/端口接收数据?

我正在查看使用 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();
                }

         }            

 }

【问题讨论】:

  • UDP 是一种无连接协议。这个问题没有意义。
  • 当我像 netstat 显示的那样关闭套接字时,端口仍然被绑定。当我尝试重新绑定时,我将进入使用异常,除非我设置了重用地址套接字选项。那讲得通。如果我设置了重用地址套接字选项,则在关闭和打开/绑定到端口后,我永远不会收到数据包。
  • 编辑了问题以摆脱连接,因为您认为 UDP 是无连接协议是正确的。我真正想知道的是 1) 有没有办法解除绑定/释放已绑定的端口。 2)当我设置 socketoption 重用地址时,我能够绑定到端口,但我从未使用该地址/端口接收数据。

标签: c# windows sockets windows-7 udp


【解决方案1】:

在调用close()时应该释放端口,所以听起来close()没有被调用或者没有成功。

删除 shutdown() 调用,因为它并不真正适用于 UDP。

检查close() 的错误返回,确保它被调用并且返回成功。

【讨论】:

  • 感谢您的回答。 close() 没有返回类型? msdn.microsoft.com/en-us/library/wahsac9k%28v=vs.90%29.aspx
  • 在方法情况下,如果底层closesocket()函数返回错误,它应该抛出异常。因此,请确保您确实达到了该声明并捕捉到任何异常。
  • 感谢您的回复。我可以单步执行代码,看到他对 socket.close() 的调用被命中并返回而不抛出异常。
  • 但是在close() 之后,netstat -a -u -p -n 仍然显示该端口号绑定到该进程?
  • 我认为你的意思是 -b 而不是 -u 但答案是肯定的。
猜你喜欢
  • 1970-01-01
  • 2014-04-28
  • 2013-01-03
  • 2012-05-07
  • 2021-01-23
  • 2017-09-15
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多