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 ); }
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); } }