Хорошо, вот мои мысли:
If two requests were made to one server at the same time, would one be denied, and if so, how could you keep something like that from happening?
В настоящее время у меня есть сервер, настроенный для приложения чата, которое я создаю, и он в основном запускает соединение TCP / IP, ждет клиента, считывает отправленные от него данные, отправляет что-то обратно, отключается и повторяется. Таким образом, сервер никогда не перестанет работать, и можно будет сделать столько запросов, сколько захотите.
Однако что, если клиент запускался, в то время как другая программа использовала сервер. Что произойдет, если одна программа получает файл с сервера, пока другая запускается, а для запуска нужны данные с сервера, но он уже занят, что произойдет?
Будет ли запуск ждать, пока сервер будет доступен, или он просто перейдет к ошибке (поскольку соединение не было доступно). Если так, это может быть очень плохо, поскольку тогда у пользователя не будет всех данных, таких как список его друзей или несколько чатов. Как ты мог это исправить?
Моя идея заключалась бы в том, чтобы вы могли настроить цикл while, чтобы он продолжал ставить сервер в очередь до тех пор, пока он не получит ответ. Это правильный способ сделать это?





Нет, клиент должен предполагать, что сервер всегда доступен. Вы увидите, что базовый метод Socket.Listen(int32) (для которого TcpListener действует как оболочка) принимает один параметр, backlog:
Listen causes a connection-oriented Socket to listen for incoming connection attempts. The backlog parameter specifies the number of incoming connections that can be queued for acceptance. To determine the maximum number of connections you can specify, retrieve the MaxConnections value. Listen does not block.
Большинство реализаций серверов начинаются примерно со следующего:
socket.Listen(10); // You choose the number
while (true)
{
var client = socket.Accept();
// Spawn a thread (or Task if you prefer), and have that do all the work for the client
var thread = new Thread(() => DoStuff(client));
thread.Start();
}
В этой реализации всегда есть поток, ожидающий новых подключений. Когда клиент подключается, для него создается новый поток, поэтому обработка для этого клиента не задерживает / не препятствует принятию дополнительных подключений в основном потоке.
Теперь, если несколько новых подключений появятся быстрее, чем сервер может создать новые потоки, тогда новые подключения будут автоматически помещены в очередь (я думаю, на уровне ОС) - параметр backlog определяет, сколько ожидающих подключений может быть в отставание сразу.
Что, если отставание полностью заполнится? На этом этапе вам понадобится второй сервер и балансировщик нагрузки, который будет действовать как посредник, направляя половину запросов на первый сервер и половину запросов на второй сервер.
Логика здесь простая.
Сервер начинает слушать и начинает принимать клиентов.
Клиент пытается подключиться к серверу. Вы можете просто ничего не делать, если сервер не работает, или вы можете реализовать некоторую логику повторного подключения, уведомляющую клиента о неудачных попытках подключения.
Предположим, что сервер был запущен, когда клиент пытался подключиться. Вы говорите о многоклиентском приложении. Не следует отключать клиента. Вам необходимо добавить подключенного клиента в список подключенных клиентов.
Затем, когда некоторые клиенты подключаются к серверу, а другие уже подключены, они отправляют какое-то сообщение. Вы получаете это сообщение через клиентский сокет, а затем транслируете сообщение всем другим подключенным клиентам, кроме того, который отправляет данные.