Ejemplo n.º 1
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
            SocketContainer co = ar.AsyncState.CastType <SocketContainer>();

            // 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
                co.Socket.EndConnect(ar); //Send

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

                IsConnected = true;
                OnConnectedCallback?.Invoke();
                //Send(SocketManager.ManagedConn(), co); // ??? --> 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
                //AsyncReceiveState mReceiveState = new AsyncReceiveState();
                //mReceiveState.Socket = mState.Socket;

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

                co.Socket.BeginReceive(co.rState.Buffer, 0, gBufferSize, SocketFlags.None, new AsyncCallback(ServerMessageReceived), co);
            }
            catch (Exception ex)
            {
                // at this point, the EndConnect failed and we are NOT connected to the server!
                myLogger.Log("Connect error: " + ex.Message);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SocketClient"/> class.
        /// </summary>
        /// <param name="ipAddr">The ip addr.</param>
        /// <param name="port">The port.</param>
        /// <param name="sType">Type of the s.</param>
        /// <param name="pType">Type of the p.</param>
        /// <param name="readEvery">The read every.</param>
        /// <param name="everyFunc">The every function.</param>
        /// <param name="doConnection">if set to <c>true</c> [do connection].</param>
        public SocketClient(IPAddress ipAddr, ushort port, SocketType sType, ProtocolType pType, Action <object, SocketContainer> everyFunc, bool doConnection = false)
        {
            //period = readEvery;

            cSendQueue.MessageQueued += cSendQueue_MessageQueued;

            ReceivedServerMessageCallback = everyFunc;
            //TimerCallback timerDelegate = new TimerCallback(Timering);

            //if (everyFunc != null)
            //    task = new Timer(timerDelegate, null, 5, readEvery);

            IP   = ipAddr;
            Port = port;

            //0 as an ID is not allowed, this is waiting for a ID
            my = new SocketContainer(0, new Socket(ipAddr.AddressFamily, sType, pType)
            {
                NoDelay = false
            });

            if (doConnection)
            {
                DoConnection();
            }
        }
Ejemplo n.º 3
0
        public void ServerMessageReceived(IAsyncResult ar)
        {
            // get the async state object from the async BeginReceive method
            //AsyncReceiveState mState = (AsyncReceiveState)ar.AsyncState;
            SocketContainer co = ar.AsyncState.CastType <SocketContainer>();

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

            numBytesReceived = co.Socket.EndReceive(ar);

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

            // increment the total bytes received so far on the state object
            co.rState.TotalBytesReceived += numBytesReceived;
            // check for the end of the packet
            // bytesReceived = Carcassonne.Library.PacketBufferSize Then
            if (co.rState.TotalBytesReceived < co.rState.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
                co.Socket.BeginReceive(co.rState.Buffer, 0, gBufferSize, SocketFlags.None, new AsyncCallback(ServerMessageReceived), co);
            }
            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!
                BinaryFormatter mSerializer = new BinaryFormatter();
                // rewind the PacketBufferStream so we can de-serialize it
                co.rState.PacketBufferStream.Position = 0;
                // de-serialize the PacketBufferStream which will give us an actual Packet object
                co.rState.Packet = mSerializer.Deserialize(co.rState.PacketBufferStream);
                // parse the complete message that was received from the server
                ParseReceivedServerMessage(co.rState.Packet, co);

                // call BeginReceive again, so we can start receiving another packet from this client socket
                co.Socket.BeginReceive(co.rState.Buffer, 0, gBufferSize, SocketFlags.None, new AsyncCallback(ServerMessageReceived), co);

                //Dispose of everything we dont need after receive message from server
                Array.Clear(co.rState.Buffer, 0, co.rState.Buffer.Length);
                co.rState.ReceiveSize        = 0;
                co.rState.Packet             = null;
                co.rState.TotalBytesReceived = 0;
                co.rState.PacketBufferStream.Close();
                co.rState.PacketBufferStream.Dispose();
                co.rState.PacketBufferStream = new MemoryStream();
            }
        }
Ejemplo n.º 4
0
 private void MessageReceived(string argMessage, SocketContainer co)
 {
     if (txtReceiveLog.Text != "")
     {
         txtReceiveLog.Text = Environment.NewLine + txtReceiveLog.Text;
     }
     txtReceiveLog.Text = co.Socket.RemoteEndPoint.ToString() + ": " + argMessage + txtReceiveLog.Text;
 }
Ejemplo n.º 5
0
        private void cSendQueue_MessageQueued()
        {
            // when a message is queued, we need to check whether or not we are currently processing the queue before allowing the top item in the queue to start sending
            if (cSendQueue.Processing == false)
            {
                // process the top message in the queue, which in turn will process all other messages until the queue is empty
                //AsyncSendState mState = (AsyncSendState)cSendQueue.Messages.Dequeue();
                SocketContainer co = cSendQueue.Messages.Dequeue().CastType <SocketContainer>();

                // we must send the correct number of bytes, which must not be greater than the remaining bytes
                co.Socket.BeginSend(co.sState.BytesToSend, co.sState.NextOffset(), co.sState.NextLength(), SocketFlags.None, new AsyncCallback(MessagePartSent), co);
            }
        }
Ejemplo n.º 6
0
        public void ParseReceivedServerMessage(object obj, SocketContainer argContainer)
        {
            Console.WriteLine("Received object of type: {0}", obj.GetType().Name);

            if (obj is string)
            {
                myLogger.Log((string)obj);
            }
            else if (obj is SocketMessage)
            {
                HandleAction((SocketMessage)obj, argContainer);
            }
        }
Ejemplo n.º 7
0
        public void Send(object obj, SocketContainer co)
        {
            // serialize the Packet into a stream of bytes which is suitable for sending with the Socket
            BinaryFormatter mSerializer = new BinaryFormatter();

            using (MemoryStream mSerializerStream = new MemoryStream())
            {
                mSerializer.Serialize(mSerializerStream, obj);

                // get the serialized Packet bytes
                byte[] mPacketBytes = mSerializerStream.GetBuffer();

                // convert the size into a byte array
                byte[] mSizeBytes = BitConverter.GetBytes(mPacketBytes.Length + 4);

                // create the async state object which we can pass between async methods
                //AsyncSendState mState = new AsyncSendState(ClientSocket);

                // resize the BytesToSend array to fit both the mSizeBytes and the mPacketBytes
                // ERROR: Not supported in C#: ReDimStatement

                if (co.sState.BytesToSend != null)
                {
                    if (co.sState.BytesToSend.Length != mPacketBytes.Length + mSizeBytes.Length)
                    {
                        Array.Resize(ref co.sState.BytesToSend, mPacketBytes.Length + mSizeBytes.Length);
                    }
                }
                else
                {
                    co.sState.BytesToSend = new byte[mPacketBytes.Length + mSizeBytes.Length];
                }

                // copy the mSizeBytes and mPacketBytes to the BytesToSend array
                Buffer.BlockCopy(mSizeBytes, 0, co.sState.BytesToSend, 0, mSizeBytes.Length);
                Buffer.BlockCopy(mPacketBytes, 0, co.sState.BytesToSend, mSizeBytes.Length, mPacketBytes.Length);

                Array.Clear(mSizeBytes, 0, mSizeBytes.Length);
                Array.Clear(mPacketBytes, 0, mPacketBytes.Length);

                Console.WriteLine("Ready to send a object of {0} bytes length", co.sState.BytesToSend.Length);

                co.Socket.BeginSend(co.sState.BytesToSend, co.sState.NextOffset(), co.sState.NextLength(), SocketFlags.None, new AsyncCallback(MessagePartSent), co);
            }
        }
Ejemplo n.º 8
0
        /// <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 = ar.AsyncState.CastType <Socket>();
            // 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
            //In the very first connection we have to send the id to the client
            ulong genID = 1;

            //Give id in a range...
            bool b = routingTable.Keys.FindFirstMissingNumberFromSequence(out genID, new MinMax <ulong>(1, (ulong)routingTable.Count));

            myLogger.Log("Adding #{0} client to routing table!", genID); //Esto ni parece funcionar bien

            SocketContainer co = new SocketContainer(genID, mClientSocket);

            if (!routingTable.ContainsKey(genID))
            {
                routingTable.Add(genID, co);
            }
            else
            {
                Console.WriteLine("Overlapping ID error!");
            }

            //We don't have a way to know if there was a problem in the transmission ???
            SendToClient(SocketManager.ReturnClientIDAfterAccept(genID), routingTable[genID]);
            ClientConnected?.Invoke(routingTable[genID]);

            routingTable[genID].Socket.BeginReceive(routingTable[genID].rState.Buffer, 0, gBufferSize, SocketFlags.None, new AsyncCallback(ClientMessageReceived), routingTable[genID]); //ClientMessageReceived
            // begin accepting another client connection
            mServerSocket.BeginAccept(new AsyncCallback(ClientAccepted), mServerSocket);
        }
Ejemplo n.º 9
0
        private void HandleAction(SocketMessage sm, SocketContainer argContainer)
        {
            //Before we connect we request an id to the master server...
            if (sm.msg is SocketCommand)
            {
                SocketCommand cmd = sm.msg.CastType <SocketCommand>();
                if (cmd != null)
                {
                    switch (cmd.Command)
                    {
                    /*case SocketCommands.CreateConnId:
                     *  myLogger.Log("Starting new CLIENT connection with ID: {0}", sm.id);
                     *  Id = sm.id;
                     *
                     *  Send(SocketManager.ConfirmConnId(Id), argContainer); //???
                     *  OnConnectedCallback?.Invoke();
                     *  break;*/

                    case SocketCommands.ReturnClientIDAfterAccept:
                        myLogger.Log("Starting new CLIENT connection with ID: {0}", sm.id);
                        Id = sm.id;
                        break;

                    case SocketCommands.CloseInstance:
                        myLogger.Log("Client is closing connection...");
                        Stop(false);
                        break;

                    default:
                        myLogger.Log("Unknown ClientCallbackion to take! Case: {0}", cmd.Command);
                        break;
                    }
                }
                else
                {
                    myLogger.Log("Empty string received by client!");
                }
            }
            else
            {
                ReceivedServerMessageCallback?.Invoke(sm.msg, argContainer);
            }
        }
Ejemplo n.º 10
0
        private void HandleAction(SocketMessage sm, SocketContainer argContainer)
        {
            //string val = sm.StringValue;
            if (sm.msg is SocketCommand)
            {
                SocketCommand cmd = sm.msg.CastType <SocketCommand>();
                if (cmd != null)
                {
                    switch (cmd.Command)
                    {
                    case SocketCommands.CloseClients:
                        CloseAllClients(sm.id);
                        break;

                    case SocketCommands.ClosedClient:
                        //closedClients.Add(sm.id);
                        SocketManager.PoliteClose(sm.id);     //Tell to the client that it has been disconnected from it
                        routingTable.Remove(sm.id);
                        CloseServerAfterClientsClose(dispose);
                        break;

                    case SocketCommands.Stop:
                        CloseAllClients(sm.id);
                        break;

                    case SocketCommands.UnpoliteStop:
                        object d = cmd.Metadata["Dispose"];
                        Stop(d != null && ((bool)d));
                        break;

                    default:
                        DoServerError(string.Format("Cannot de-encrypt the message! Unrecognized 'enum' case: {0}", cmd.Command), sm.id);
                        break;
                    }
                }
            }
            else
            {
                //If not is a command, then send the object to other clients...
                SendToClient(sm, sm.DestsId);
            }
        }
Ejemplo n.º 11
0
        public void ParseReceivedClientMessage(object obj, SocketContainer argContainer)
        {
            //Aquí ocurre la magia
            if (obj is string)
            {
                string argCommandString = (string)obj;

                myLogger.Log("");
                //myLogger.Log("ParseReceivedClientMessage: " + argCommandString);

                // parse the command string
                string argCommand = null;
                string argText    = null;

                if (argCommandString.StartsWith("/"))
                {
                    argCommand = argCommandString.Substring(0, argCommandString.IndexOf(" "));
                    argText    = argCommandString.Remove(0, argCommand.Length + 1);
                }
                else
                {
                    argText = argCommandString;
                }

                switch (argText)
                {
                case "hi server":
                    SendMessageToClient("/say Server replied.", argContainer);
                    break;
                }

                MessageReceived?.Invoke(argCommandString, argContainer);
            }
            else if (obj is SocketMessage)
            {
                HandleAction((SocketMessage)obj, argContainer);
            }

            //This is a server-only method, that is called for "Debugging purpouses" by the moment
            ReceivedClientMessageCallback?.Invoke(obj, argContainer);
            //Check there in case of ((SocketMessage)obj).DestsId[0] == 0??
        }
Ejemplo n.º 12
0
        public void MessagePartSent(IAsyncResult ar)
        {
            // get the async state object which was returned by the async beginsend method
            //AsyncSendState mState = (AsyncSendState)ar.AsyncState;
            SocketContainer co = ar.AsyncState.CastType <SocketContainer>();

            try
            {
                int numBytesSent = 0;
                // call the EndSend method which will succeed or throw an error depending on if we are still connected
                numBytesSent = co.Socket.EndSend(ar);

                // increment the total amount of bytes processed so far
                co.sState.Progress += numBytesSent;

                // determine if we havent' sent all the data for this Packet yet
                if (co.sState.NextLength() > 0)
                {
                    // we need to send more data
                    co.Socket.BeginSend(co.sState.BytesToSend, co.sState.NextOffset(), co.sState.NextLength(), SocketFlags.None, new AsyncCallback(MessagePartSent), co);
                }
                else
                {
                    Console.WriteLine("Client MessagePartSent completed. Clearing stuff...");

                    //Reset for the next time
                    Array.Clear(co.sState.BytesToSend, 0, co.sState.BytesToSend.Length);

                    Array.Resize(ref co.sState.BytesToSend, gBufferSize);
                }
                // at this point, the EndSend succeeded and we are ready to send something else!
                // TODO: use the queue to determine what message was sent and show it in the local chat buffer
                //RaiseEvent MessageSentToServer()
            }
            catch (Exception ex)
            {
                myLogger.Log("DataSent error: " + ex.Message);
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// QueueMessage prepares a Message object containing our data to send and queues this Message object in the OutboundMessageQueue.
        /// </summary>
        /// <remarks></remarks>
        public void SendToClient(object obj, SocketContainer co)
        {
            // serialize the Packet into a stream of bytes which is suitable for sending with the Socket
            BinaryFormatter mSerializer = new BinaryFormatter();

            using (MemoryStream mSerializerStream = new MemoryStream())
            {
                mSerializer.Serialize(mSerializerStream, obj);

                // get the serialized Packet bytes
                byte[] mPacketBytes = mSerializerStream.GetBuffer();

                // convert the size into a byte array
                byte[] mSizeBytes = BitConverter.GetBytes(mPacketBytes.Length + 4);

                // create the async state object which we can pass between async methods
                //AsyncSendState mState = new AsyncSendState(argClient);

                // resize the BytesToSend array to fit both the mSizeBytes and the mPacketBytes
                // TODO: ReDim mState.BytesToSend(mPacketBytes.Length + mSizeBytes.Length - 1)
                Array.Resize(ref co.sState.BytesToSend, mPacketBytes.Length + mSizeBytes.Length);

                // copy the mSizeBytes and mPacketBytes to the BytesToSend array
                Buffer.BlockCopy(mSizeBytes, 0, co.sState.BytesToSend, 0, mSizeBytes.Length);
                Buffer.BlockCopy(mPacketBytes, 0, co.sState.BytesToSend, mSizeBytes.Length, mPacketBytes.Length);

                Array.Clear(mSizeBytes, 0, mSizeBytes.Length);
                Array.Clear(mPacketBytes, 0, mPacketBytes.Length);

                Console.Write("");

                // queue the Message
                Console.WriteLine("Server (SendToClient): NextOffset: {0}; NextLength: {1}", co.sState.NextOffset(), co.sState.NextLength());
                co.Socket.BeginSend(co.sState.BytesToSend, co.sState.NextOffset(), co.sState.NextLength(), SocketFlags.None, new AsyncCallback(MessagePartSent), co);
            }
        }
Ejemplo n.º 14
0
 private void ClientDisconnected(SocketContainer co)
 {
     listBox1.Items.Remove(co.Socket.RemoteEndPoint);
 }
Ejemplo n.º 15
0
 public void SendMessageToServer(string argCommandString, SocketContainer container)
 {
     Send(argCommandString, container);
 }
Ejemplo n.º 16
0
        /// <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
            //AsyncReceiveState mState = (AsyncReceiveState)ar.AsyncState;
            SocketContainer co = ar.AsyncState.CastType <SocketContainer>();

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

            try
            {
                numBytesReceived = co.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(co);
                    return;
                }
            }

            // if we get numBytesReceived equal to zero, it could indicate that the client has disconnected
            if (numBytesReceived == 0)
            {
                ClientDisconnected?.Invoke(co);
                return;
            }

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

            // increment the total bytes received so far on the state object
            co.rState.TotalBytesReceived += numBytesReceived;
            // check for the end of the packet
            // bytesReceived = Carcassonne.Library.PacketBufferSize Then
            if (co.rState.TotalBytesReceived < co.rState.ReceiveSize)
            {
                //File.AppendAllText(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "serverAppend.txt"), string.Join(" ", co.rState.Buffer.Select(x => x.ToString())) + " ");

                // ## 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
                co.Socket.BeginReceive(co.rState.Buffer, 0, gBufferSize, SocketFlags.None, new AsyncCallback(ClientMessageReceived), co);
            }
            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!
                BinaryFormatter mSerializer = new BinaryFormatter();
                // rewind the PacketBufferStream so we can de-serialize it
                co.rState.PacketBufferStream.Position = 0;
                // de-serialize the PacketBufferStream which will give us an actual Packet object
                co.rState.Packet = mSerializer.Deserialize(co.rState.PacketBufferStream);
                Console.WriteLine("Succesfully deserialized object of type: {0}", co.rState.Packet.GetType().Name);
                // handle the message
                ParseReceivedClientMessage(co.rState.Packet, co);
                // call BeginReceive again, so we can start receiving another packet from this client socket
                //AsyncReceiveState mNextState = new AsyncReceiveState();
                //mNextState.Socket = mState.Socket;

                // ???

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

                co.Socket.BeginReceive(co.rState.Buffer, 0, gBufferSize, SocketFlags.None, new AsyncCallback(ClientMessageReceived), co);

                //Dispose of everything we dont need after receive message from client
                Array.Clear(co.rState.Buffer, 0, co.rState.Buffer.Length);
                co.rState.ReceiveSize        = 0;
                co.rState.Packet             = null;
                co.rState.TotalBytesReceived = 0;
                co.rState.PacketBufferStream.Close();
                co.rState.PacketBufferStream.Dispose();
                co.rState.PacketBufferStream = new MemoryStream();
            }
        }
Ejemplo n.º 17
0
 /// <summary>
 /// QueueMessage prepares a Message object containing our data to send and queues this Message object in the OutboundMessageQueue.
 /// </summary>
 /// <remarks></remarks>
 public void SendMessageToClient(string argCommandString, SocketContainer argContainer)
 {
     SendToClient(argCommandString, argContainer);
 }
Ejemplo n.º 18
0
 private static void server_MessageReceived(string argMessage, SocketContainer argContainer)
 {
     Console.WriteLine("Received message of {0} bytes length.", argMessage.Length);
 }
Ejemplo n.º 19
0
 private void server_ClientDisconnected(SocketContainer argContainer)
 {
     Invoke(new ClientDisconnectedDelegate(ClientDisconnected), argContainer);
 }
Ejemplo n.º 20
0
 private void server_MessageReceived(string argMessage, SocketContainer argContainer)
 {
     Invoke(new MessageReceivedDelegate(MessageReceived), new object[] { argMessage, argContainer });
 }
Ejemplo n.º 21
0
 public void Add(SocketContainer argContainer)
 {
     Messages.Enqueue(argContainer);
     MessageQueued?.Invoke();
 }