0

I tried to socket programming with AcceptAsync and SocketAsyncEventArgs. I wrote my code if Client access to Server, AcceptAsync make completed event and try to receive. But when I try. Client Socket completly access to Server Socket. But Server's AcceptAsync return 'true' and don't make Completed Event. By the way, In Debug Mode, AcceptAsync's blocking is true and AcceptAsync return 'false' and Client and Server Socket send and recv each other by manually call OnAccecptCompleted Method.

I tried to this similar Questioin's Solution.

My Server Code is this :

Socket _listenerSocket;
    Action<Socket> _onAcceptHandler;

    public void Init(IPEndPoint endPoint, Action<Socket> onAcceptHandler) {
        Console.WriteLine("Init");
        _listenerSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        _onAcceptHandler += onAcceptHandler;

        _listenerSocket.Bind(endPoint);

        _listenerSocket.Listen(10);

        SocketAsyncEventArgs args = new SocketAsyncEventArgs();
        args.SetBuffer(null, 0, 0);
        args.Completed += new EventHandler<SocketAsyncEventArgs>(OnAccecptCompleted);
        RegisterAccept(args);
    }

    void RegisterAccept(SocketAsyncEventArgs args) {
        Console.WriteLine("RegisterAccept");
        args.AcceptSocket = null;
        try {
            bool pending = _listenerSocket.AcceptAsync(args);
            Console.WriteLine($"pending {pending}");
            if (pending == false) {
                Console.WriteLine("RegisterAccept_pending==false");
                OnAccecptCompleted(null, args);
            }
        }
        catch(Exception e) {
            Console.WriteLine(e.ToString);
        }
        
    }

    void OnAccecptCompleted(object sender, SocketAsyncEventArgs args) {
        Console.WriteLine("OnAcceptCompleted");
        if(args.SocketError == SocketError.Success) {
            _onAcceptHandler.Invoke(args.AcceptSocket);
        }
        else {
            Console.WriteLine(args.SocketError.ToString());
        }

        RegisterAccept(args);
    }

My endPoint arg's Code is this :

        string host = Dns.GetHostName();
        IPHostEntry ipHost = Dns.GetHostEntry(host);
        IPAddress ipAddr = ipHost.AddressList[0];
        IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);

My OnAcceptHandler Method code is this :

static void OnAcceptHandler(Socket clientSocket) {
        try {
            // Recv
            byte[] recvBuff = new byte[1024];
            int recvByte = clientSocket.Receive(recvBuff);
            string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvByte);
            Console.WriteLine($"[From Client] : {recvData}");

            // Send
            byte[] sendBuff = Encoding.UTF8.GetBytes("Welcome  to Server!");
            clientSocket.Send(sendBuff);

            // DisConnect
            //clientSocket.Shutdown(SocketShutdown.Both);
            clientSocket.Close();
        }
        catch(Exception e) {
            Console.WriteLine(e.ToString());
        }

    }

When AcceptAsync don't make 'Completed Event', My socket status is like this. enter image description here

  • Add 01 : I fix this problem but It just temporary solution. After Init() I tried to Thread.Sleep(), Send / Recv Problem is fixed. I don't know why but it works. If someone know why this happen or guess why, please comment under this question. Thanks.

  • Add 02 : If Thread.Sleep()'s time is low, Socket communicate is stop on Client's Socket.Recv part and Server's AcceptAsync doesn't make Completed Event.

Fixed Server's Main() :

static void Main(string[] args) {

        // DNS
        string host = Dns.GetHostName();
        IPHostEntry ipHost = Dns.GetHostEntry(host);
        IPAddress ipAddr = ipHost.AddressList[0];
        IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);

        //Console.WriteLine($"host : {host}, ipHost : {ipHost}, ipAddr : {ipAddr}, endPoint : {endPoint.Address}");

        // set Listener Socket
        _listener.Init(endPoint, OnAcceptHandler);
        Console.WriteLine("Listening...");
        Thread.Sleep(2000);
        //Console.WriteLine(_listener.args.SocketError ); 
        while (true) {
            ;
        }
    }
  • Add 03 : if Thread.Sleep Work in While(), It Client and Sernver's communicatioin is never stop.(sometimes delay but never stop)

This is Fixed code :

static void Main(string[] args) {

        // DNS
        string host = Dns.GetHostName();
        IPHostEntry ipHost = Dns.GetHostEntry(host);
        IPAddress ipAddr = ipHost.AddressList[0];
        IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);

        //Console.WriteLine($"host : {host}, ipHost : {ipHost}, ipAddr : {ipAddr}, endPoint : {endPoint.Address}");

        // set Listener Socket
        _listener.Init(endPoint, OnAcceptHandler);
        Console.WriteLine("Listening...");
        
        //Console.WriteLine(_listener.args.SocketError ); 
        while (true) {
            Thread.Sleep(1);
        }
    }

I guess this is Mac's work assign Policy issue. Am I right?

Namk0207
  • 45
  • 5
  • 1
    Is there any reason you are not using `TcpListener` and `NetworkStream` and `StreamReader`, which would simplify things significantly? Also you should use `async` `await` instead of callbacks – Charlieface Jul 29 '22 at 12:47
  • I'm beginner at Socket Programming and that code is based from guided code by my study. Thanks for introduce TcpListner, NetworkStream, StreamReader, async and await. I'll refer and study about that. Thanks. – Namk0207 Aug 01 '22 at 06:05

0 Answers0