Сразу скажу что не очень хорошо знаком с сетью. Вернее с архитектурой сетевого слоя. Но проблема уже есть :)
Предыстория: есть клиент-серверная игра для iOS. Есть удаленный сервер (не наш, но доступ к нему есть полный). Исходники и клиента и сервера есть - они мне достались в наследство от програмиста, который утверждает что сетевой слой там хреново спроектирован и реализован. По сути так и есть...
Как это работает сейчас: каждые N секунд каждому клиенту с сервера отправляется ping пакет. То же самое делает клиент (т.е так же каждые N секунд отправляет ping серверу). Если по прошествии M секунд данные не были получены, то соединение закрывается (как на клиенте, так и на сервере). По сути выглядит логично. Постоянно онлайн играет где-то 40-50 человек.
Проблема: она состоит в том, что почти каждую минуту (судя по логам на сервере) мы получаем ошибку сокета "Broken Pipe". Судя по всему клиент закрывает соединение, но сервер об этом еще ничего не знает (но я не уверен, так ли это).
Вопрос: как это делается по нормальному и можно ли какими-то минимальными средствами устранить это? Желательно конечно обойтись только изменением сервера, потому что выпускать обновление для клиента пока нет возможности.
Добавлено: N = 2сек, M = 10*N = 20сек, сервер написан на С++, протокол - TCP
Пинги на чём сделаны? HTTP?
Удалённый сервер на чём сделан? Какой-то стандартный веб сервер?
Тогда открывай соединение HTTP/1.1 и флаг Connection: Keep-Alive и дальше работай такими же пингами как и раньше, должно прокатить.
Потребуется модификация в клиенте, чтобы по возможности не закрывал соединение, а если оно закрылось - чтобы переоткрывал.
Если в клиенте явно написано socket.close(), то как ты на сервере не модифицируй, клиент со своей стороны дверцу захлопнет. Надо его модифицировать.
kvakvs
Да, забыл сказать - сервер написан на С++ и использует сокеты для отправки/приема данных
А в логах не пишется что это за клиент, жалобы от игроков есть? Может просто чтото левое постоянно конектится неизветсно для чего а потом отваливается?
VBKesha
> жалобы от игроков есть?
Полно. Отваливаются все подряд
Какой тип соеденения TCP/UDP какова разница между временем N и временем M?
Соединение TCP
M = 10*N
Ну то есть это в принципе правильный путь, только реализован через ж**у, как я понимаю, да?
И вообще какое время N
две секунды
За 2 секунды брокен-пайп это помоему уже проблема не в сети а чтото с клиентами они почемуто отрубают сокеты гдето видимо косяк.
Sergio
у нас пакеты идут постоянно, и если после последнего пакета прошло больше чем время М - рвем соединение... тоже периодически глючит, поэтому время М сейчас около 30 секунд..
реализовано нормально.
встречал подобную схему N = 10 ( c ) и M = 2 * N работала, как часы.
что можно посоветовать....
поставить сервер на одну машину... поставить клиента на другую между ними дохрена свичей и маршрутизаторов понавтыкать... врубить проги по анализу TCP трафика. И ждать... Более посоветовать сложно.
Сокеты и TCP - это значит, что если клиент корректно закрывает соединение,
то сервер не может об этом незнать, или же код на сервере написан с ошибкой,
или на клиенте некоректно сделано закрытие соединения.
То что описано выше, это не keep-alive, это проверка - не отвалился ли клиент (не висит ли дохлое соединение, когда клиент давным давно вырубился, некорректно вырубился). Это тогда check-is-alive.
Zakus
> то сервер не может об этом незнать, или же код на сервере написан с ошибкой,
> или на клиенте некоректно сделано закрытие соединения.
А можно поподробнее...
Насколько я знаю соединение закрывается с помощью close() как на клиенте, так и на сервере. А как отловить закрытие соединения с другой стороны?
> А как отловить закрытие соединения с другой стороны?
Протокол TCP содержит в себе уведомление о закрытии соединения. Так что, если клиент сделал close(), то на сервер придет соответствующий TCP пакет. И наоборот, соответственно.
Тема в архиве.