C# some ASYNC Tcp Programming question

Newbie Spellweaver
Joined
Jun 1, 2014
Messages
48
Reaction score
2
Hey, i got a question^^
I rebuilded some of my old network Programms and i wanted to ask if someone could tell me if the Code is okey and what could i improove :)

This is the Client Handler callback:
Code:
 private void HandleClient(IAsyncResult ar)        {
            StateObject state = (StateObject)ar.AsyncState;
            [COLOR=#ff0000]handler = state.workSocket;[/COLOR]


            if(!IsSocketConnected(handler))
            {
                handler.Close();
                return;
            }


            int bytesRead = handler.EndReceive(ar);
            if(bytesRead > 0)
            {
                /*Dispatch*/
                byte[] inputMessage = new byte[bytesRead];
                Array.Copy(state.buffer, inputMessage, bytesRead);
                byte bOP = inputMessage[7];
                Network.inputHandler.Dispatch(inputMessage,(Network.Enums.INPUT_OPCODE)bOP);
                /*Dispatch*/
       


            }
            else
            {
                handler.Close();
            }


              
        }
I dont know if its okey or not, but i set the handler Public like this:
Code:
        public static Socket handler;
so that i can easy access it from another Class but i think this might be wrong(?)

I created a Little function to send easy my packets:
Code:
  public static void Send(Socket handler, byte[] data)        {        
            handler.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), handler);
        }

And i need to call it with the handler from my Program.cs is this okey or should i do it difrrent? im afraid that if i handle some more clients it wont work ^^
 
Yeah thats exacly was i thought seems like i need to find an other solution..

You could raise a event everytime a client got accepted.

This is my old ConnectionAcceptor, you could see how things are done and then you should be able to rewrite it with BeginAccept etc.
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;


namespace Networking
{
    /// <summary>
    /// Class used for accepting connections.
    /// </summary>
    public class ConnectionAcceptor
    {
        /// <summary>
        /// Represents the connection acceptor.
        /// </summary>
        private Socket Listener;
        /// <summary>
        /// A value that indicates whether the acceptor is accepting.
        /// </summary>
        public Boolean Accepting { get; private set; }




        /// <summary>
        /// Represent the AcceptSAEA
        /// </summary>
        private SocketAsyncEventArgs AcceptSAEA;


        /// <summary>
        /// A event that occurs whether a connection has been accepted.
        /// </summary>
        public event Action<Socket> Accepted;
        /// <summary>
        /// A event that occurs whether a fatal stop (exception) occurs while accepting.
        /// </summary>
        public event Action<Exception> FatalStopped;


        /// <summary>
        /// Event that occurs when the <see cref="Networking.ConnectionAcceptor"/> started accepting.
        /// </summary>
        public event Action Started;
        /// <summary>
        /// Event that occurs when the <see cref="Networking.ConnectionAcceptor"/> stopped accepting.
        /// </summary>
        public event Action Stopped;


        /// <summary>
        /// A Method that is used to start accepting connection.
        /// </summary>
        /// <param name="ip">The ip to accept connections of.</param>
        /// <param name="port">The port to use.</param>
        public void BeginAccept(IPAddress ip, ushort port)
        {
            if (Accepting)
                return;


            Listener = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            Listener.Bind(new IPEndPoint(ip, port));
            Listener.Listen(15);
            Accepting = true;


            AcceptSAEA = new SocketAsyncEventArgs();
            AcceptSAEA.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptCallBack);


            if (!Listener.AcceptAsync(AcceptSAEA))
                AcceptCallBack(null, AcceptSAEA);


            RaiseStarted();


        }
        /// <summary>
        /// CallBack that occurs whether the AsyncAccept operation has proceed.
        /// </summary>
        private void AcceptCallBack(object sender, SocketAsyncEventArgs e)
        {
            if (Listener == null)
            {
                return;
            }
            else if (e.SocketError == SocketError.Success)
            {
                RaiseAccepted(e.AcceptSocket);
            }


            e.AcceptSocket = null;


            try
            {
                if (!Listener.AcceptAsync(e))
                    AcceptCallBack(null, e);
            }
            catch (Exception ex)
            {
                InnerStop(true, ex);
            }
        }


        /// <summary>
        /// Stops accepting connections.
        /// </summary>
        public void Stop()
        {
            if (!Accepting)
                return;


            InnerStop(false, null);
        }
        /// <summary>
        /// Stops accepting connections.
        /// </summary>
        /// <param name="FatalStop">Determine whether the stop is a fatal stop</param>
        /// <param name="ex">If it is a fatal stop, the exception that occurs.</param>
        private void InnerStop(bool FatalStop, Exception ex)
        {
            if (!Accepting)
                return;


            Accepting = false;


            AcceptSAEA.Dispose();
            AcceptSAEA = null;


            Listener.Dispose();
            Listener = null;






            if (FatalStop)
            {
                RaiseFatalStop(ex);
            }
            else
            {
                RaiseStopped();
            }


        }


        /// <summary>
        /// Raises the Accepted event.
        /// </summary>
        /// <param name="sock">The accepted socket.</param>
        private void RaiseAccepted(Socket sock)
        {
            if (Accepted != null)
                Accepted(sock);
        }
        /// <summary>
        /// Raises the FatalStop event.
        /// </summary>
        /// <param name="ex">The exception that occurs.</param>
        private void RaiseFatalStop(Exception ex)
        {
            if (FatalStopped != null)
                FatalStopped(ex);
        }


        /// <summary>
        /// Raises the Stopped event.
        /// </summary>
        private void RaiseStopped()
        {
            if (Stopped != null)
                Stopped();
        }
        /// <summary>
        /// Raises the Started event.
        /// </summary>
        private void RaiseStarted()
        {
            if (Started != null)
                Started();
        }
    }
}
 
Last edited:
Yeah thats exacly was i thought seems like i need to find an other solution..

THere should be some kind of event that is being triggered. If you create a new socket and add it to a list, all sockets are being active and one will not write another as the objects do not get disposed (/ garbage collected).
 
Just google them , already writed :P

msdn asynchronus socket server
msdn asynchronus socket client
msdn synchronuse socket server
msdn synchronuse socket client
 
By looking at it... and remembering i had to write like a few thousand additional lines just to protect from tricky user behaviour, stuck connections, router packets failure, sudden internet failure, floods, garbage, and so on... u must read 2-3 books on C# TCP, check thepiratebay, else i dont see how u can make anything stable...

Just google them , already writed :P

msdn asynchronus socket server
msdn asynchronus socket client
msdn synchronuse socket server
msdn synchronuse socket client


These are obviously not the most stable examples, but its a start.
 
Back