Java TCP / IP Server неправильно закрывает соединения - PullRequest
0 голосов
/ 03 декабря 2010

Я создал MMO для телефона Android и использую сервер Java с сокетами TCP / IP. В целом все работает нормально, но примерно через день, когда клиенты входят в систему и выходят из нее, моя сеть становится крайне медленной - даже если клиенты не подключены. NETSTAT не показывает длительных соединений, но, очевидно, происходит что-то ужасно неправильное.

Если я сделаю полную перезагрузку, все снова будет волшебным, но это не надёжное решение в долгосрочной перспективе. Вот как выглядит мой метод отключения (на обоих концах):

    public final void disconnect()
{
    Alive = false;
    Log.write("Disconnecting " + _socket.getRemoteSocketAddress());
    try
    {
        _socket.shutdownInput();
    }
    catch (final Exception e)
    {
        Log.write(e);
    }
    try
    {
        _socket.shutdownOutput();
    }
    catch (final Exception e)
    {
        Log.write(e);
    }
    try
    {
        _input.close();
    }
    catch (final Exception e)
    {
        Log.write(e);
    }
    try
    {
        _output.close();
    }
    catch (final Exception e)
    {
        Log.write(e);
    }
    try
    {
        _socket.close();
    }
    catch (final Exception e)
    {
        Log.write(e);
    }
}

_input и _output - это BufferedInputStream и BufferedOutputStream, порожденные из сокета. В соответствии с документацией, вызывать shutdownInput () и shutdownOutput () не нужно, но я выкидываю на это все, что возможно.

Я создаю экземпляры сокетов с настройками по умолчанию - я не касаюсь soLinger, KeepAlive, noDelay или чего-то в этом роде. У меня не установлены таймауты при отправке / получении. Я пытался использовать WireShark, но он не обнаружил ничего необычного, как NETSTAT.

Я довольно отчаянно нуждаюсь в ответах на этот вопрос. Я вложил много усилий в этот проект и разочарован тем, что кажется серьезным скрытым недостатком в реализации TCP по умолчанию в Java.

Ответы [ 2 ]

2 голосов
/ 04 декабря 2010

Избавьтесь от shutdownInput () и shutdownOutput () и всех закрытий, кроме закрытия для BufferedOutputStream и последующего закрытия самого сокета в блоке finally в виде пояса и фигурных скобок. Вы закрываете и закрываете все остальное перед выходным потоком, что предотвращает его сброс. Закрытие выходного потока очищает его и закрывает сокет. Это все, что вам нужно.

0 голосов
/ 08 декабря 2010

OP здесь, невозможно прокомментировать исходное сообщение.

  • Перезапуск процесса на сервере не решает проблему.Сеть остается очень «зависшей» даже через несколько минут после полного отключения сервера.

  • Под «отставанием» я подразумеваю, что соединение становится очень медленным как с восходящим, так и с отключенным трафиком.Попытка загрузить веб-сайты или загрузить их на мой FTP мучительно медленна, как будто я использую модем 14.4k (я использую волокно 15 Мбит / с).Тесты скорости интернета даже не работают, когда он находится в этом состоянии - я получаю ошибку о том, что не могу найти файл, когда веб-сайты в конечном итоге загружаются.

  • Все это мгновенно очищаетсяпосле перезагрузки и только после перезагрузки.

  • Я изменил метод отключения, как предложил EJP, но проблема сохраняется.

  • Серверработает на Windows 7, последняя версия Java / Java SDK.Сервер имеет 16 ГБ ОЗУ, хотя, возможно, я не выделяю его должным образом, чтобы JVM полностью использовала его.Кажется, что нет никаких случайных потоков или процессов.Я посмотрю, что говорит JVISUALVM.- jysend 13 минут назад

  • Ничего необычного в JVISUALVM - куча 10 Мб, загрузка процессора 50%, 3160 объектов (ожидается), 27 активных потоков из 437 запущены.Сервер работает около 18 часов;загрузка главной страницы CNN занимает около минуты, и обычный тест скорости, который я использую (первый тест скорости поиска в Google), даже не загружает страницу.NETSTAT не показывает длительных соединений.Запустил все современные антивирусы.Сервер работал 24/7 без каких-либо проблем - только когда я запустил на нем этот Java-сервер, это начало происходить.

...