Example #1
0
        /// <summary>
        /// This callback is for handling the receive of the size header.
        /// </summary>
        /// <param name="ar"></param>
        private void ReceiveSizeCallback(IAsyncResult ar)
        {
            try {
                //Attempt to end the read
                var read = socket.EndReceive(ar);

                /*An exception should be thrown on EndReceive if the connection was lost.
                 * However, that is not always the case, so we check if read is zero or less.
                 * Which means disconnection.
                 * If there is a disconnection, we throw an exception*/
                if (read <= 0)
                {
                    throw new SocketException((int)SocketError.ConnectionAborted);
                }

                //increment the total data read
                dataRead += read;

                //If we didn't receive the full buffer size, something is lagging behind.
                if (dataRead < SIZE_HEADER)
                {
                    //Begin receive again
                    BeginReceive();

                    //If we did receive the full header, then begin reading the payload
                }
                else
                {
                    dataRead = 0;

                    //Get the converted int value for the payload size from the received data
                    dataExpected = BitConverter.ToInt32(buffer, 0);

                    if (dataExpected == NetConstants.PING_REQUEST)
                    {
                        SendPingResponse();
                        BeginReceive();
                        return;
                    }
                    else if (dataExpected == NetConstants.PING_RESPONSE)
                    {
                        double ping = ((double)pingWatch.ElapsedTicks / Stopwatch.Frequency) * 1000.0;
                        Ping = ping;
                        BeginReceive();
                        PingUpdated?.Invoke(this, ping);
                        pingWatch.Restart();
                        return;
                    }

                    if (dataExpected > ClientOptions.MaxPacketSize)
                    {
                        throw new ProtocolViolationException($"Illegal payload size: payload size exeeded whats max allowed {dataExpected} > {ClientOptions.MaxPacketSize}");
                    }
                    else if (dataExpected < ClientOptions.MinPacketSize)
                    {
                        throw new ProtocolViolationException($"Illegal payload size: payload size is less than allowed {dataExpected} < {ClientOptions.MinPacketSize}");
                    }
                    else if (dataExpected == 0)
                    {
                        throw new ProtocolViolationException("Illegal payload size: payload had no length");
                    }
                    else
                    {
                        /*If the expected data size is bigger than what
                         * we can hold we need to write it to a resizable stream */
                        if (dataExpected > buffer.Length)
                        {
                            //Initialize a new MemStream to receive chunks of the payload
                            payloadStream = new MemoryStream(ClientOptions.BufferSize);

                            //Start the receive loop of the payload
                            socket.BeginReceive(buffer, 0, buffer.Length, 0,
                                                ReceivePayloadStreamCallback, null);
                        }
                        else
                        {
                            //Else we receive directly into the buffer
                            socket.BeginReceive(buffer, 0, dataExpected, 0,
                                                ReceivePayloadBufferedCallback, null);
                        }
                    }
                }
            } catch (NullReferenceException) {
                return;
            } catch (ObjectDisposedException) {
                return;
            } catch (Exception ex) {
                HandleDisconnect(ex);
            }
        }
Example #2
0
 private void ProtocolClient_PingUpdated(ProtocolClient sender, double ping)
 {
     PingUpdated?.Invoke(sender, ping);
 }