Conversation
| using SimpleFtp.Protocol; | ||
|
|
||
| var server = new FtpServer(); | ||
| await server.Listen(); |
There was a problem hiding this comment.
Здесь нужен механизм корректной остановки сервера. Например, по нажатию на какую-нибудь клавишу
| var response = client.SendRequest(request); | ||
| Console.Write(response.ToString()); | ||
| response = client.SendRequest(request); | ||
| Console.Write(response.ToString()); |
| namespace SimpleFtp; | ||
| public class FtpServer | ||
| { | ||
| private const int Port = 21; |
There was a problem hiding this comment.
Здесь специально используется 21 порт, на котором обычный FTP работает? :)
Оригинально, но надо на другой заменить. Лучше на 1024+, потому что первые 1024 зарезервированы для часто используемых служб
| public async Task Listen() | ||
| { | ||
| _listener.Start(); | ||
| while (true) |
There was a problem hiding this comment.
Надо добавить возможность остановки сервера, использовать CancellationToken и передавать его в _listener.AcceptTcpClientAsync()
| while (true) | ||
| { | ||
| using var client = await _listener.AcceptTcpClientAsync(); | ||
| await HandleClient(client); |
There was a problem hiding this comment.
Если await-ить работу с клиентами, то нарушается условие -- сервер не может параллельно несколько запросов обрабатывать. Ожидалась передача задачи работы с клиентами в отдельный поток, например, с помощью Task.Run
There was a problem hiding this comment.
Также надо будет не забывать эти задачи сохранять, чтобы завершать работу сервера только после закрытия всех соединений с клиентами
|
|
||
| public abstract class Request | ||
| { | ||
| public abstract string ToString(); |
There was a problem hiding this comment.
Здесь аналогично предупреждения ниже
| private StreamReader? _reader; | ||
| private StreamWriter? _writer; | ||
| public string Hostname { get; private set; } | ||
| public int Port { get; private set; } |
There was a problem hiding this comment.
Свойства надо ниже конструктора перенести
| } | ||
| } | ||
| } | ||
| } No newline at end of file |
| Console.Write($"Request: {data}"); | ||
| var response = HandleRequest(RequestFactory.Create(data)); | ||
| await writer.WriteAsync(response.ToString()); | ||
| Console.Write($"Response: {response.ToString()}"); |
There was a problem hiding this comment.
А это зачем?
Клиент же и так в своём program выводит ответ. Там же виден и запрос.
Надо стараться UI выносить вне реализации. Да и вряд ли пользователь захочет увидеть набор байтов какого-нибудь бинарника :)
| public Response SendRequest(Request request) | ||
| { | ||
| _writer?.Write(request.ToString()); | ||
| var data = _reader?.ReadLine() + "\n"; |
There was a problem hiding this comment.
В случае get-запроса ответ некорректно считается: \n может раньше конца команды оказаться -- внутри содержимого файла.
Еще в случае get-запроса лучше передавать содержимое файла в поток, который предоставит пользователь. Чтобы файл напрямую в память не читать (так как он большой может быть), а предоставить право выбора вызывающему
No description provided.