Пример #1
0
        protected void AcceptCallback(IAsyncResult result)
        {
            var listener = result.AsyncState as Socket;
            var handler  = listener.EndAccept(result);

            handler.Send(this.welcomeMessage);

            ClientConnectionState state = new ClientConnectionState(handler);

            handler.BeginReceive(
                state.Buffer,
                0,
                handler.Available <= 64000 ? handler.Available : 64000,
                0,
                new AsyncCallback(ReadCallback),
                state
                );
        }
Пример #2
0
        protected void DecodeMessage(ClientConnectionState state)
        {
            if (state.Buffer.Length < 2)
            {
                throw new InvalidOperationException("ERROR DECODE Buffer length is invalid");
            }
            string msg = Encoding.ASCII.GetString(state.Buffer, 0, Math.Min(10, state.Buffer.Length));

            IPAddress ip = (state.Socket.RemoteEndPoint as IPEndPoint).Address ?? null;

            /* Protocol reading section */
            if (msg.StartsWith("LOGIN ")) // Connecting to server
            {
                msg = Encoding.ASCII.GetString(state.Buffer, 6, Math.Min(300, state.Buffer.Length));
                string[] arguments = msg.Split(' ');
                if (arguments.Length != 4 || arguments[0] != "HOST" || arguments[2] != "PASS")
                {
                    state.Buffer = null;
                    state.Socket.Send(this.invalidMessage);
                }
                string host = arguments[1];
                string pass = arguments[3];
                if (pass.Length != 8 || pass != CurrentPassword)
                {
                    state.Buffer = null;
                    state.Socket.Send(Encoding.ASCII.GetBytes("INVALID PASS"));
                }
                CurrentPassword = GeneratePassword();

                ClientConnectedEventArgs e = new ClientConnectedEventArgs();
                e.Server       = this;
                e.UtcTime      = DateTime.UtcNow;
                state.Password = e.Password = pass;
                e.Hostname     = host;
                state.ClientId = e.ClientId = Guid.NewGuid();
                e.IP           = ip;
                OnClientConnected?.Invoke(this, e);
            }
            else if (msg.StartsWith("FILE ADD\0")) // Start new file transfer
            {
                ReadonlyStream stream = new ReadonlyStream(state.Buffer);
                stream.Position = 9;
                using (BinaryReader reader = new BinaryReader(stream))
                {
                    try
                    {
                        Guid clientid = new Guid(reader.ReadBytes(16));

                        Client client = ConnectedClients.Where(item => item.Id == clientid && item.IP == ip).First();
                        if (client is null)
                        {
                            state.Buffer = null;
                            state.Socket.Send(Encoding.ASCII.GetBytes("ABORTED"));
                        }

                        if (reader.ReadByte() != 0)
                        {
                            state.Buffer = null;
                            state.Socket.Send(Encoding.ASCII.GetBytes("INVALID MESSAGE"));
                        }

                        string filename = string.Empty;
                        char   c;
                        while ((c = reader.ReadChar()) != 0)
                        {
                            filename += c;
                        }

                        ulong size = reader.ReadUInt64();
                        TransferRequestEventArgs e = new TransferRequestEventArgs();;
                        e.Client   = client;
                        e.Filename = filename;
                        e.Id       = Guid.NewGuid();
                        e.Server   = this;
                        e.Size     = size;
                        e.UtcTime  = DateTime.UtcNow;
                        OnTransferRequest?.Invoke(this, e);
                        e.Server = this;
                        if (!e.IsAccepted || e.IsCanceled)
                        {
                        }
                        if (e.Stream is null || !e.Stream.CanWrite)
                        {
                        }
                    }
                    catch (EndOfStreamException)
                    {
                        state.Buffer = null;
                        state.Socket.Send(Encoding.ASCII.GetBytes("INVALID MESSAGE"));
                    }
                }
            }
            else if (msg.StartsWith("FILE STOP\0")) // Abort file transfer
            {
            }
            else if (msg.StartsWith("FILE DATA\0")) // Set data block of file
            {
            }
            else if (msg.StartsWith("LOGOUT\0")) // Close connection
            {
            }
            else // Invalid message
            {
                state.Buffer = null;
                state.Socket.Send(this.invalidMessage);
            }
        }