예제 #1
0
        /// <summary>
        /// Alg 4.
        /// </summary>
        /// <param name="client">Instance clienta</param>
        /// <param name="version">Domluvena verze</param>
        private async void HandleMessages( TcpClient client, int version ) {
            var networkStream = client.GetStream();
            var cancelClient = new CancellationTokenSource();
            try {
                while( true ) {
                    //Vytvoreni tasku pro odpojeni clienta, pokud 180sec neposle ping
                    if( version > 0 )
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                        Task.Run( () => Task.Delay( 180000, cancelClient.Token ).
                            ContinueWith( ( x ) => DisconnectClient( client ), cancelClient.Token ) );
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed

                    //Task pro prijmuti zpravy od clienta 
                    byte[] buffer = new byte[ 4096 ];
                    int bufferSize = await networkStream.ReadAsync( buffer, 0, buffer.Length );
                    Message msg = Message.ParseMsgFromBytes( buffer, bufferSize );

                    //Prisla zprava typu Msg, tak ji preposlu vsem clientum
                    if( msg.MsgType == Msg.MSG ) {
                        byte[] toBroadcast = msg.ToByteArray();
                        foreach( var other in Clients ) {
                            if(other.Connected)
                                await other.GetStream().WriteAsync( toBroadcast, 0, toBroadcast.Length );
                        }
                    }

                    //Prisla zprava typu Ping, takze zrusim predchozi task na pingovani a vytvorim novy pro dalsich 180sec 
                    //a jeste odeslu clientovi pong
                    if(version > 0 && msg.MsgType == Msg.PING ) {
                        cancelClient.Cancel();
                        cancelClient = new CancellationTokenSource();
                        var pong = new Message( Msg.PONG, DateTime.Now, 1 ).ToByteArray();
                        await networkStream.WriteAsync( pong, 0, pong.Length );
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                        Task.Run( () => Task.Delay( 180000, cancelClient.Token ).
                            ContinueWith( ( x ) => DisconnectClient( client ), cancelClient.Token ) );
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    }
                }
            }
            catch( ObjectDisposedException ) {
                window.AddTextLine( "Error Server: HandleMessages() ObjectDisposedException" );
                this.Stop();
                return;
            }
            catch( System.IO.IOException ) {
                window.AddTextLine( "Error Server: HandleMessages() IOException" );
                this.Stop();
                return;
            }
            catch( Exception e ) {
                System.Windows.MessageBox.Show( "Unknown Server error: " + e.Message );
                this.Stop();
                return;
            }
        }
예제 #2
0
        /// <summary>
        /// Alg 3.
        /// </summary>
        /// <param name="client">Instance clienta</param>
        /// <returns></returns>
        private async Task<int> SendHandshake( TcpClient client ) {
            var networkStream = client.GetStream();

            byte[] buffer = new byte[ 4096 ];

            //WAITING FOR HELLO
            int bufferSize = await networkStream.ReadAsync( buffer, 0, buffer.Length );
            var helloMsg = Message.ParseMsgFromBytes( buffer, bufferSize );
            if(helloMsg.MsgType != Msg.HELLO ) //Pokud prislo neco jinyho nez hello, tak odpojim clienta (zpatny pro DDOS)
                DisconnectClient( client );
            
            string[] bodySplits = helloMsg.Body.Split( ' ' );
            string latestVersion = bodySplits[ bodySplits.Length - 1 ];
            int intVersion = latestVersion == "1.1" ? 1 : 0;

            //ACCEPTED HELLO, SENDING OLLEH
            var ollehBytes = new Message( Msg.OLLEH, DateTime.Now, intVersion ).ToByteArray();
            await networkStream.WriteAsync( ollehBytes, 0, ollehBytes.Length );

            //OLLEH SENT, WAITING FOR ACK
            bufferSize = await networkStream.ReadAsync( buffer, 0, buffer.Length );
            var ackMsg = Message.ParseMsgFromBytes( buffer, bufferSize );
            if( ackMsg.MsgType != Msg.ACK ) //Pokud prislo neco jinyho nez ack, tak odpojim clienta (zpatny protokol)
                DisconnectClient( client );
            
            //ACCEPTED ACK
            return intVersion;
        }
예제 #3
0
        /// <summary>
        /// Alg 4.
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        private async Task InitializeConnection( string username ) {
            byte[] buffer = new byte[ 4096 ];

            //SENDING HELLO
            var hello = new Message( Msg.HELLO, DateTime.Now, 1 );
            var helloBytes = hello.ToByteArray();
            await stream.WriteAsync( helloBytes, 0, helloBytes.Length );

            //WAITING FOR OLLEH
            int bufferSize = await stream.ReadAsync( buffer, 0, buffer.Length );
            var olleh = Message.ParseMsgFromBytes( buffer, bufferSize );
            if( olleh.MsgType != Msg.OLLEH )
                throw new Exception( "Got something else than OLLEH packet" );

            //ACCEPTED OLLEH, SENDING ACK
            var ackBytes = new Message( Msg.ACK, DateTime.Now, 1 ).ToByteArray();
            await stream.WriteAsync( ackBytes, 0, ackBytes.Length );

            //CONNECTED
        }
예제 #4
0
        /// <summary>
        /// Metoda pro odesilani zprav typu "MSG" na server
        /// </summary>
        /// <param name="message"></param>
        public async void SendMessage( string message ) {
            if( !client.Connected ) {
                System.Windows.MessageBox.Show( "Cannot send messages (not connected)" );
                return;
            }

            var msgBytes = new Message( Msg.MSG, DateTime.Now, 1, message, username ).ToByteArray();
            
            await stream.WriteAsync( msgBytes, 0, msgBytes.Length );
        }
예제 #5
0
 /// <summary>
 /// Nekonecny task pro posilani pingu po 60sec.
 /// Vytvari se s pingCancelation tokenem pro jeho zruseni pri Disconnectu
 /// </summary>
 private async void SendPing() {
     var ping = new Message( Msg.PING, DateTime.Now, 1 ).ToByteArray();
     await stream.WriteAsync( ping, 0, ping.Length );
     try {
         await Task.Delay( 60000 ).ContinueWith( ( x ) => SendPing(), pingCancelation.Token );
     }
     catch( TaskCanceledException ) {
     }
 }