/// <summary>
        /// ClientConnected is a callback that gets called when the server accepts a client connection from the async BeginAccept method.
        /// </summary>
        /// <param name="ar"></param>
        /// <remarks></remarks>
        public void ClientAccepted(IAsyncResult ar)
        {
            // get the async state object from the async BeginAccept method, which contains the server's listening socket
            Socket mServerSocket = (Socket)ar.AsyncState;
            // call EndAccept which will connect the client and give us the the client socket
            Socket mClientSocket = null;

            try
            {
                mClientSocket = mServerSocket.EndAccept(ar);
            }
            catch //(ObjectDisposedException ex)
            {
                // if we get an ObjectDisposedException it that means the server socket terminated while this async method was still active
                return;
            }
            // instruct the client to begin receiving data
            SocketGlobals.AsyncReceiveState mState = new SocketGlobals.AsyncReceiveState();
            mState.Socket = mClientSocket;
            ClientConnected?.Invoke(mState.Socket);
            mState.Socket.BeginReceive(mState.Buffer, 0, SocketGlobals.gBufferSize, SocketFlags.None, new AsyncCallback(ClientMessageReceived), mState);
            // begin accepting another client connection
            mServerSocket.BeginAccept(new AsyncCallback(ClientAccepted), mServerSocket);

            //mServerSocket.Dispose(); // x?x?
            //Console.WriteLine("Server ClientAccepted => CompletedSynchronously: {0}; IsCompleted: {1}", ar.CompletedSynchronously, ar.IsCompleted);
        }
Esempio n. 2
0
        /// <summary>
        /// Fires right when a client is connected to the server.
        /// </summary>
        /// <param name="ar"></param>
        /// <remarks></remarks>
        public void ConnectToServerCompleted(IAsyncResult ar)
        {
            // get the async state object which was returned by the async beginconnect method
            SocketGlobals.AsyncSendState mState = (SocketGlobals.AsyncSendState)ar.AsyncState;

            // end the async connection request so we can check if we are connected to the server
            try
            {
                // call the EndConnect method which will succeed or throw an error depending on the result of the connection
                mState.Socket.EndConnect(ar);

                // at this point, the EndConnect succeeded and we are connected to the server!
                // send a welcome message

                Send(SocketManager.ManagedConn()); // ??? --> el problema estába en que estaba llamado a Socket.Send directamente y estamos dentro de un Socket async xD

                // start waiting for messages from the server
                SocketGlobals.AsyncReceiveState mReceiveState = new SocketGlobals.AsyncReceiveState();
                mReceiveState.Socket = mState.Socket;

                Console.WriteLine("Client ConnectedToServer => CompletedSynchronously: {0}; IsCompleted: {1}", ar.CompletedSynchronously, ar.IsCompleted);

                mReceiveState.Socket.BeginReceive(mReceiveState.Buffer, 0, SocketGlobals.gBufferSize, SocketFlags.None, new AsyncCallback(ServerMessageReceived), mReceiveState);

                //mReceiveState.Socket.Dispose(); // x?x? n
            }
            catch (Exception ex)
            {
                // at this point, the EndConnect failed and we are NOT connected to the server!
                myLogger.Log("Connect error: " + ex.Message);
            }
        }
        /// <summary>
        /// BeginReceiveCallback is an async callback method that gets called when the server receives some data from a client socket after calling the async BeginReceive method.
        /// </summary>
        /// <param name="ar"></param>
        /// <remarks></remarks>
        public void ClientMessageReceived(IAsyncResult ar)
        {
            // get the async state object from the async BeginReceive method
            SocketGlobals.AsyncReceiveState mState = (SocketGlobals.AsyncReceiveState)ar.AsyncState;

            // call EndReceive which will give us the number of bytes received
            int numBytesReceived = 0;

            try
            {
                numBytesReceived = mState.Socket.EndReceive(ar);
            }
            catch (SocketException ex)
            {
                // if we get a ConnectionReset exception, it could indicate that the client has disconnected
                if (ex.SocketErrorCode == SocketError.ConnectionReset)
                {
                    ClientDisconnected?.Invoke(mState.Socket);
                    return;
                }
            }
            // if we get numBytesReceived equal to zero, it could indicate that the client has disconnected
            if (numBytesReceived == 0)
            {
                ClientDisconnected?.Invoke(mState.Socket);
                return;
            }

            // determine if this is the first data received
            if (mState.ReceiveSize == 0)
            {
                // this is the first data recieved, so parse the receive size which is encoded in the first four bytes of the buffer
                mState.ReceiveSize = BitConverter.ToInt32(mState.Buffer, 0);
                // write the received bytes thus far to the packet data stream
                mState.PacketBufferStream.Write(mState.Buffer, 4, numBytesReceived - 4);
            }
            else
            {
                // write the received bytes thus far to the packet data stream
                mState.PacketBufferStream.Write(mState.Buffer, 0, numBytesReceived);
            }

            // increment the total bytes received so far on the state object
            mState.TotalBytesReceived += numBytesReceived;
            // check for the end of the packet
            // bytesReceived = Carcassonne.Library.PacketBufferSize Then
            if (mState.TotalBytesReceived < mState.ReceiveSize)
            {
                // ## STILL MORE DATA FOR THIS PACKET, CONTINUE RECEIVING ##
                // the TotalBytesReceived is less than the ReceiveSize so we need to continue receiving more data for this packet
                mState.Socket.BeginReceive(mState.Buffer, 0, SocketGlobals.gBufferSize, SocketFlags.None, new AsyncCallback(ClientMessageReceived), mState);
            }
            else
            {
                // ## FINAL DATA RECEIVED, PARSE AND PROCESS THE PACKET ##
                // the TotalBytesReceived is equal to the ReceiveSize, so we are done receiving this Packet...parse it!
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter mSerializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                // rewind the PacketBufferStream so we can de-serialize it
                mState.PacketBufferStream.Position = 0;
                // de-serialize the PacketBufferStream which will give us an actual Packet object
                mState.Packet = mSerializer.Deserialize(mState.PacketBufferStream);
                Console.WriteLine("Succesfully deserialized object of type: {0}", mState.Packet.GetType().Name);
                // handle the message
                ParseReceivedClientMessage(mState.Packet, mState.Socket);
                // call BeginReceive again, so we can start receiving another packet from this client socket
                SocketGlobals.AsyncReceiveState mNextState = new SocketGlobals.AsyncReceiveState();
                mNextState.Socket = mState.Socket;

                // ???
                mState.PacketBufferStream.Close();
                mState.PacketBufferStream.Dispose();
                mState.PacketBufferStream = null;
                Array.Clear(mState.Buffer, 0, mState.Buffer.Length);

                Console.WriteLine("Server ClientMessageReceived => CompletedSynchronously: {0}; IsCompleted: {1}", ar.CompletedSynchronously, ar.IsCompleted);

                mNextState.Socket.BeginReceive(mNextState.Buffer, 0, SocketGlobals.gBufferSize, SocketFlags.None, new AsyncCallback(ClientMessageReceived), mNextState);

                //mState.Socket.Dispose(); // x?x?
                mState = null;
            }
        }