Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

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 ^^
 
Newbie Spellweaver
Joined
Jun 1, 2014
Messages
48
Reaction score
2
Yeah thats exacly was i thought seems like i need to find an other solution..
 
BloopBloop
Joined
Aug 9, 2012
Messages
892
Reaction score
275
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:
Joined
Sep 30, 2010
Messages
728
Reaction score
107
Just google them , already writed :p

msdn asynchronus socket server
msdn asynchronus socket client
msdn synchronuse socket server
msdn synchronuse socket client
 
Moderator
Staff member
Moderator
Joined
Feb 22, 2008
Messages
2,404
Reaction score
723
And you should also add code to handle partial packets, since when you send bytes or receive from client, the data could get split into 2 packets for example. You need to account for that in your recv method.
 
Custom Title Activated
Loyal Member
Joined
Sep 10, 2006
Messages
5,265
Reaction score
47
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
Top