Пример #1
0
        public AClient(Socket nSocket, bool beginReceive)
        {
            ClientID = ClientIDCounter;
            ClientIDCounter++;

            ClientSocket = nSocket;

            // Setup read data callback.
            if (beginReceive)
            {
                AClientStateObject ACS = new AClientStateObject();
                ACS.WorkSocket = ClientSocket;
                ClientSocket.BeginReceive(ACS.buffer, 0, AClientStateObject.BufferSize, 0, new AsyncCallback(ReadCallback), ACS);
            }
        }
Пример #2
0
        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                Socket ClientSocket = (Socket)ar.AsyncState;
                ClientSocket.EndConnect(ar);

                AClientStateObject ACS = new AClientStateObject();
                ACS.WorkSocket = ClientSocket;
                ClientSocket.BeginReceive(ACS.buffer, 0, AClientStateObject.BufferSize, 0, new AsyncCallback(ReadCallback), ACS);
            }
            catch (ObjectDisposedException ex)
            {
                Core.Output("Client could not connect.");
            }
            catch (SocketException ex)
            {
                Core.Output("Client could not connect.");
            }
            catch (Exception ex)
            {
                Core.HandleEx("AClient:ConnectCallback", ex);
            }
        }
Пример #3
0
        // Example of useage: http://msdn.microsoft.com/en-us/library/fx6588te.aspx

        private void ReadCallback(IAsyncResult ar)
        {
            try
            {
                AClientStateObject ACS          = (AClientStateObject)ar.AsyncState;
                Socket             ClientSocket = ACS.WorkSocket;

                int bytesRead = ClientSocket.EndReceive(ar);
                int offset    = 0;
                while (offset < bytesRead)
                {
                    int bytesRemaining = bytesRead - offset;
                    if (!ACS.ReadingData)
                    {
                        // Data length is unknown.
                        int bytesInMemoryStream   = (int)ACS.MStream.Length;
                        int bytesNeededFromPacket = DATA_LENGTH_SIZE - bytesInMemoryStream;

                        if (bytesInMemoryStream > 0)
                        {
                            // We have partial data length bytes in memory stream.
                            if (bytesNeededFromPacket <= bytesRemaining)
                            {
                                // There is enough data length bytes in packet to complete data length.
                                byte[] dataLengthBytes = new byte[DATA_LENGTH_SIZE];
                                if (bytesInMemoryStream >= DATA_LENGTH_SIZE)
                                {
                                    Core.Output("This should never happen, check it out!");
                                }
                                ACS.MStream.Read(dataLengthBytes, 0, bytesInMemoryStream);
                                Array.Copy(ACS.buffer, offset, dataLengthBytes, bytesInMemoryStream, bytesNeededFromPacket);
                                offset         += bytesNeededFromPacket;
                                ACS.DataLength  = BitConverter.ToInt32(dataLengthBytes, 0);
                                ACS.ReadingData = true;
                            }
                            else
                            {
                                // Not enough bytes in packet to complete data length. Put them in the memory stream.
                                ACS.MStream.Write(ACS.buffer, offset, bytesRemaining);
                                offset += bytesRemaining;
                            }
                        }
                        else
                        {
                            // We have no partial data length bytes. All must be in packet.
                            if (bytesNeededFromPacket <= bytesRemaining)
                            {
                                // We have enough data length bytes in packet to complete data length.
                                byte[] dataLengthBytes = new byte[DATA_LENGTH_SIZE];
                                Array.Copy(ACS.buffer, offset, dataLengthBytes, 0, bytesNeededFromPacket);
                                offset += bytesNeededFromPacket;

                                int dataLength = BitConverter.ToInt32(dataLengthBytes, 0);
                                if (dataLength == 0)
                                {
                                    Core.Output("STOPPP");
                                }
                                ACS.DataLength  = BitConverter.ToInt32(dataLengthBytes, 0);
                                ACS.ReadingData = true;
                            }
                            else
                            {
                                // Not enough bytes in packet to complete data length. Put them in the memory stream.
                                ACS.MStream.Write(ACS.buffer, offset, bytesRemaining);
                                offset += bytesRemaining;
                            }
                        }
                    }
                    else
                    {
                        // Data length is known.
                        if (ACS.BytesRead + bytesRemaining >= ACS.DataLength)
                        {
                            // We have enough bytes to complete reading the data.
                            int bytesToRead = ACS.DataLength - ACS.BytesRead;
                            ACS.MStream.Write(ACS.buffer, offset, bytesToRead);
                            ACS.BytesRead += bytesToRead;
                            offset        += bytesToRead;

                            Core.Output("Data transmission successful, received " + ACS.MStream.Length + " bytes.");
                            //if (OnDataRead != null)
                            //OnDataRead(ACS.MStream.ToArray(), this);

                            ACS.Reset();
                        }
                        else
                        {
                            // Not enough data to complete message. Add remainder to memory stream.
                            ACS.MStream.Write(ACS.buffer, offset, bytesRemaining);
                            ACS.BytesRead += bytesRemaining;
                            offset        += bytesRemaining;
                        }
                    }
                }

                Core.Output("MSTREAM: " + ACS.MStream.Length);

                // Get more data.
                ClientSocket.BeginReceive(ACS.buffer, 0, AClientStateObject.BufferSize, 0,
                                          new AsyncCallback(ReadCallback), ACS);
            }
            catch (ObjectDisposedException ex)
            {
                // Thrown upon closing client.
            }
            catch (SocketException ex)
            {
                // When client runs in the problems, it likely means a disconnect, so cleanup socket.
                Close();
            }
            catch (Exception ex)
            {
                Core.HandleEx("AClient:ReadCallback", ex);
            }
        }
        /// <summary>
        /// Helper method to read incoming packet data. The packet begins with a
        /// LONG determining the size of the data, followed by the data itself. There
        /// are 4 scenarios to handle with this setup:
        /// 1. Receive a partial data length.
        /// 2. Receive the data length and partial data.
        /// 3. Receive data length, data, and a partial data length of the next message.
        /// 4. Receive data length, data, the data length of the next message, and
        ///    partial data of that next message.
        /// </summary>
        public static void HandleReadCallback(AClientStateObject ACS, int bytesRead)
        {
            try
            {
                int offset = 0;

                while (offset < bytesRead)
                {
                    int bytesRemaining = bytesRead - offset;

                    if (!ACS.ReadingData)
                    {
                        // Data length is unknown.
                        int bytesInMemoryStream   = (int)ACS.MStream.Length;
                        int bytesNeededFromPacket = DATA_LENGTH_SIZE - bytesInMemoryStream;

                        if (bytesInMemoryStream > 0)
                        {
                            // We have partial data length bytes in memory stream.
                            if (bytesNeededFromPacket <= bytesRemaining)
                            {
                                // There is enough data length bytes in packet to complete data length.
                                byte[] dataLengthBytes = new byte[DATA_LENGTH_SIZE];
                                if (bytesInMemoryStream >= DATA_LENGTH_SIZE)
                                {
                                    Core.Output("This should never happen, check it out!");
                                }
                                ACS.MStream.Read(dataLengthBytes, 0, bytesInMemoryStream);
                                Array.Copy(ACS.buffer, offset, dataLengthBytes, bytesInMemoryStream, bytesNeededFromPacket);
                                offset         += bytesNeededFromPacket;
                                ACS.DataLength  = BitConverter.ToInt32(dataLengthBytes, 0);
                                ACS.ReadingData = true;
                            }
                            else
                            {
                                // Not enough bytes in packet to complete data length. Put them in the memory stream.
                                ACS.MStream.Write(ACS.buffer, offset, bytesRemaining);
                                offset += bytesRemaining;
                            }
                        }
                        else
                        {
                            // We have no partial data length bytes. All must be in packet.
                            if (bytesNeededFromPacket <= bytesRemaining)
                            {
                                // We have enough data length bytes in packet to complete data length.
                                byte[] dataLengthBytes = new byte[DATA_LENGTH_SIZE];
                                Array.Copy(ACS.buffer, offset, dataLengthBytes, 0, bytesNeededFromPacket);
                                offset         += bytesNeededFromPacket;
                                ACS.DataLength  = BitConverter.ToInt32(dataLengthBytes, 0);
                                ACS.ReadingData = true;
                            }
                            else
                            {
                                // Not enough bytes in packet to complete data length. Put them in the memory stream.
                                ACS.MStream.Write(ACS.buffer, offset, bytesRemaining);
                                offset += bytesRemaining;
                            }
                        }
                    }
                    else
                    {
                        // Data length is known.
                        if (ACS.BytesRead + bytesRemaining >= ACS.DataLength)
                        {
                            // We have enough bytes to complete reading the data.
                            int bytesToRead = ACS.DataLength - ACS.BytesRead;
                            ACS.MStream.Write(ACS.buffer, offset, bytesToRead);
                            ACS.BytesRead += bytesToRead;
                            offset        += bytesToRead;

                            Core.Output("Data transmission successful, received " + ACS.MStream.Length + " bytes.");
                            byte[] message = new byte[ACS.DataLength];
                            ACS.MStream.Read(message, 0, ACS.DataLength);

                            // TODO: Set off OnDataRead event and handle received data!

                            ACS.Reset();
                        }
                        else
                        {
                            // Not enough data to complete message. Add remainder to memory stream.
                            ACS.MStream.Write(ACS.buffer, offset, bytesRemaining);
                            ACS.BytesRead += bytesRemaining;
                            offset        += bytesRemaining;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Core.HandleEx("AClientReadCallbackHelper:HandleCallback", ex);
            }
        }