How can I unbind a socket in C#?

后端 未结 2 520
隐瞒了意图╮
隐瞒了意图╮ 2021-01-06 05:38

I\'m having some problems reusing a server socket in a test application I\'ve made. Basically, I have a program that implements both the client side and the server side. I r

相关标签:
2条回答
  • 2021-01-06 06:25

    I agree with the previous answer, you should also "shutdown" to allow any existing activity to complete and then close the socket flagging it for reuse...

    socket.Shutdown(SocketShutdown.Both);
    socket.Disconnect(true);
    
    0 讨论(0)
  • 2021-01-06 06:30

    There may be a couple of reasons why the port would stay open, but I think you should be able to resolve your issue by using an explicit LingerOption on the socket:

    LingerOption lo = new LingerOption(false, 0);
    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo);
    

    This basically turns the socket shutdown into an abortive shutdown instead of a graceful shutdown. If you want it to be graceful but just not wait as long, then use true in the constructor and specify a small but nonzero value for the timeout.

    I just noticed this line, which is almost undoubtedly part of your problem:

    server.connection = server.connection.EndAccept(iar); // I will only have one client, so I don't care for the original listening socket.
    

    The comment you've written here is, well, wrong. Your wrapper class really shouldn't allow connection to be written to at all. But you cannot simply replace the listening socket with the client socket - they're two different sockets!

    What's going to happen here is that (a) the listening socket goes out of scope and therefore never gets explicitly closed/disposed - this will happen at a random time, possibly at a nasty time. And (b) the socket that you do close is just the client socket, it will not close the listening socket, and so it's no wonder that you're having trouble rebinding another listening socket.

    What you're actually witnessing isn't a socket timeout, it's the time it takes for the garbage collector to realize that the listening socket is dead and free/finalize it. To fix this, you need to stop overwriting the listening socket; the Dispose method of your wrapper class should dispose the original listening socket, and the client socket should be tracked separately and disposed whenever you are actually done with it.

    In fact, you should really never need to rebind another listening socket at all. The listening socket stays alive the whole time. The actual connection is represented by just the client socket. You should only need to dispose the listening socket when you finally shut down the server.

    0 讨论(0)
提交回复
热议问题