locked
Check if socket is listening RRS feed

  • Question

  • Below is my sample code to create an Asynchronous server.

    Code is fairly simple, I create a listening socket and set the asynchronous callback function

    In the callback function I accept the connection and then set the new socket to receive data.

    On receipt of data I process it and then set the socket to receive data again.

    If the client disconnects I catch in with some general checks (works for the purposes of this example).


    My question is... how do I check if my main listening socket is still listening?

    For example if my program is running, it will sleep for 5 seconds then "check the socket". What I want to do is if the socket is not listening to set it to listen.

    I've run into some issues where if I disable the network card on the computer and re-enable it, my listening socket is no longer listening (and if I recall correctly there were no errors thrown). I would assume this is not the only scenario in which the socket could "stop listening".

    I've tried using the Poll method, but I received False with the network card enabled and disabled.

    Any ideas? (Below is the code I used in my example)

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ConsoleApplication1
    {
        class Packet
        {
            public System.Net.Sockets.Socket socket;
            public byte[] buffer = new byte[10];
        }
        
        class Program
        {
            static System.Net.Sockets.Socket socket;
    
            static void Main(string[] args)
            {
                Init();
                while (true)
                {
                    CheckSocket();
                    System.Threading.Thread.Sleep(5000);
                }
            }
    
            static void Init()
            {
                socket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
                socket.Bind(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 9600));
                socket.Listen(10);
                socket.BeginAccept(new AsyncCallback(onConnect), null);
            }
    
            static void onConnect(IAsyncResult asyn)
            {
                System.Net.Sockets.Socket worker = socket.EndAccept(asyn);
                Console.WriteLine(worker.Handle.ToString() + " Connect");
                WaitForData(worker);
                socket.BeginAccept(new AsyncCallback(onConnect), null);
            }
    
            static void WaitForData(System.Net.Sockets.Socket worker)
            {
                Packet packet = new Packet();
                packet.socket = worker;
                try
                {
                    worker.BeginReceive(packet.buffer, 0, packet.buffer.Length, System.Net.Sockets.SocketFlags.None, new AsyncCallback(onReceive), packet);
                }
                catch
                {
                    Console.WriteLine(worker.Handle.ToString() + " Disconnect");
                }
            }
    
            static void onReceive(IAsyncResult asyn)
            {
                Packet packet = (Packet)asyn.AsyncState;
    
                int Rx;
    
                try
                {
                    Rx = packet.socket.EndReceive(asyn);
                }
                catch
                {
                    Console.WriteLine(packet.socket.Handle.ToString() + " Disconnect");
                    return;
                }
    
                if (Rx == 0)
                {
                    Console.WriteLine(packet.socket.Handle.ToString() + " Disconnect");
                    return;
                }
    
                char[] chars = new char[Rx];
                Encoding.UTF8.GetChars(packet.buffer, 0, Rx, chars, 0);
    
                string data = new string(chars);
    
                Console.WriteLine(packet.socket.Handle.ToString() + " " + data);
    
                WaitForData(packet.socket);
            }
    
            static void CheckSocket()
            {
                Console.WriteLine(socket.Handle.ToString() + " " + socket.Poll(1, System.Net.Sockets.SelectMode.SelectRead).ToString());
            }
        }
    }
    
    Friday, April 17, 2009 3:22 AM

Answers

  • Unless you are not getting any exception from the listening part, i think this is one workaround to achieve the same.
    Thanks, A.m.a.L | [Remember to click "mark as answered" when you get a correct reply to your question]
    Friday, April 17, 2009 8:18 PM

All replies

  • I still can't figure this out or find any information regarding it.

    Help would be appreciated! Thanks
    Friday, April 17, 2009 6:31 PM
  • Start a thread that will periodically connect to server(use Sytem.Timers.Timer).
    In this thread if you are unable to connect or any socket exception reinitialize Listener.
    Thanks, A.m.a.L | [Remember to click "mark as answered" when you get a correct reply to your question]
    Friday, April 17, 2009 6:48 PM
  • Start a thread that will periodically connect to server(use Sytem.Timers.Timer).
    In this thread if you are unable to connect or any socket exception reinitialize Listener.
    Thanks, A.m.a.L | [Remember to click "mark as answered" when you get a correct reply to your question]


    Interesting solution.... Is this the only/best way to accomplish what I need?
    Friday, April 17, 2009 8:11 PM
  • Unless you are not getting any exception from the listening part, i think this is one workaround to achieve the same.
    Thanks, A.m.a.L | [Remember to click "mark as answered" when you get a correct reply to your question]
    Friday, April 17, 2009 8:18 PM
  • I know this reply may be late, but I don't see this information posted much anywhere in regards to C#; I had to resort back to the WinSock2 C API for the answer.  Hope this helps someone else looking for the answer!

    public Boolean IsListening
    {
        get
        {
            // NOTE: probably wise to add some exception handling
            Int32 optVal = (Int32)_mySocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.AcceptConnection);
            if (0 >= optVal) return false;
            return true;
        }
    }


    • Edited by fsgale Monday, June 19, 2017 2:55 PM var name typed wrong in code
    Monday, June 19, 2017 2:54 PM
  • Below is my sample code to create an Asynchronous server.

    Code is fairly simple, I create a listening socket and set the asynchronous callback function

    In the callback function I accept the connection and then set the new socket to receive data.

    On receipt of data I process it and then set the socket to receive data again.

    If the client disconnects I catch in with some general checks (works for the purposes of this example).


    My question is... how do I check if my main listening socket is still listening?

    For example if my program is running, it will sleep for 5 seconds then "check the socket". What I want to do is if the socket is not listening to set it to listen.

    I've run into some issues where if I disable the network card on the computer and re-enable it, my listening socket is no longer listening (and if I recall correctly there were no errors thrown). I would assume this is not the only scenario in which the socket could "stop listening".

    I've tried using the Poll method, but I received False with the network card enabled and disabled.

    Any ideas? (Below is the code I used in my example)

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ConsoleApplication1
    {
        class Packet
        {
            public System.Net.Sockets.Socket socket;
            public byte[] buffer = new byte[10];
        }
        
        class Program
        {
            static System.Net.Sockets.Socket socket;
    
            static void Main(string[] args)
            {
                Init();
                while (true)
                {
                    CheckSocket();
                    System.Threading.Thread.Sleep(5000);
                }
            }
    
            static void Init()
            {
                socket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
                socket.Bind(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 9600));
                socket.Listen(10);
                socket.BeginAccept(new AsyncCallback(onConnect), null);
            }
    
            static void onConnect(IAsyncResult asyn)
            {
                System.Net.Sockets.Socket worker = socket.EndAccept(asyn);
                Console.WriteLine(worker.Handle.ToString() + " Connect");
                WaitForData(worker);
                socket.BeginAccept(new AsyncCallback(onConnect), null);
            }
    
            static void WaitForData(System.Net.Sockets.Socket worker)
            {
                Packet packet = new Packet();
                packet.socket = worker;
                try
                {
                    worker.BeginReceive(packet.buffer, 0, packet.buffer.Length, System.Net.Sockets.SocketFlags.None, new AsyncCallback(onReceive), packet);
                }
                catch
                {
                    Console.WriteLine(worker.Handle.ToString() + " Disconnect");
                }
            }
    
            static void onReceive(IAsyncResult asyn)
            {
                Packet packet = (Packet)asyn.AsyncState;
    
                int Rx;
    
                try
                {
                    Rx = packet.socket.EndReceive(asyn);
                }
                catch
                {
                    Console.WriteLine(packet.socket.Handle.ToString() + " Disconnect");
                    return;
                }
    
                if (Rx == 0)
                {
                    Console.WriteLine(packet.socket.Handle.ToString() + " Disconnect");
                    return;
                }
    
                char[] chars = new char[Rx];
                Encoding.UTF8.GetChars(packet.buffer, 0, Rx, chars, 0);
    
                string data = new string(chars);
    
                Console.WriteLine(packet.socket.Handle.ToString() + " " + data);
    
                WaitForData(packet.socket);
            }
    
            static void CheckSocket()
            {
                Console.WriteLine(socket.Handle.ToString() + " " + socket.Poll(1, System.Net.Sockets.SelectMode.SelectRead).ToString());
            }
        }
    }
    
    

    Your code looks OK your doing the listen asynchronously which is correct and seems OK.

    Why should pulling the network card have any impact on the accept (listen)?

    If you begin to listen, reset the network adapter, then attempt to connect (from somewhere else on the network) then are you telling us that the async callback for BeginAccept is never called?

    I've not tried this msyelf but have done a ton of async work with servers and sockets.

    Monday, June 19, 2017 7:35 PM