Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot Close Socket After BeginAccept Method

I have a program in c# in which i create a socket, binding it, begin listening and then using beginaccept! but then when I try to close\shutdown the socket I get exceptions from the beginaccept AsyncCallback method!

     private void start_listening()
        {

            main_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint iplocal = new IPEndPoint(IPAddress.Any, 11150);
            main_socket.Bind(iplocal);
            main_socket.Listen(5);
            main_socket.BeginAccept(new AsyncCallback(OnClientConnect), null);
          }


        private void Disconnect_Click(object sender, EventArgs e)
        {
            main_socket.Shutdown(SocketShutdown.Both);
            main_socket.Close();
        }

        public void OnClientConnect(IAsyncResult asyn)
        {

            try
            {
                clients[connected_clients] = new Client("CHANGEME", "127.0.0.1", this);
                clients[connected_clients].Socket = main_socket.EndAccept(asyn);
                clients[connected_clients].WaitForData();
                main_socket.BeginAccept(OnClientConnect, null);
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message);
            }
}

many thanks!

like image 259
Hipno Avatar asked Dec 29 '22 11:12

Hipno


2 Answers

When main_socket is closed, OnClientConnect() will be called but main_socket.EndAccept() is supposed to throw an ObjectDisposedException. Perhaps you want to catch that exception and treat it as a "The listener socket has been closed" message.

The other problem with your code is that main_socket is not actually connected to anything. Calling main_socket.Shutdown() in Disconnect_Click() might throw too, but this time it should be a SocketException saying that the socket is not connected. I would remove that main_socket.Shutdown() call.

like image 55
Gonzalo Avatar answered Jan 12 '23 02:01

Gonzalo


Old topic, but one solution is: Keep a local variable, to keep track of when you "close/shutdown" the socket. I use _isShutdown.

When you start listening on the socket, set _isShutDown = False;
Before you close the socket, set _isShutdown = True;

In the EndAccept(iar) function, only call

 socket.EndAccept() when _isShutdown is false
<pre><code>
if (_isShutdown == false)
{
 someWorkSocket = listenSocket.EndAccept(iaSyncResult);
 //...
}
else
{
//socket is closed, and we shouldn't use it. Should erase this else clause..
}

like image 31
andrew_buckau Avatar answered Jan 12 '23 03:01

andrew_buckau