Проблема закрытия сокета FreeBSD - PullRequest
0 голосов
/ 22 апреля 2011

У меня проблема с методом xSocket close () во FreeBSD. Несмотря на то, что я ищу его в Google, я не смог найти ни одного удовлетворительного решения. Позвольте мне объяснить проблему немного подробнее;

У меня есть код, который открывает порты и прослушивает соединение. Я использую xSocket для этого. Особенно это для многопользовательской игры. Когда пользователь хочет настроить игру, я назначаю порты для пользователя, и пользователь может создать игру и ждать других игроков. Когда игрок закрывает свой веб-браузер или выходит из игры, если размер онлайн-игрока в созданной игре меньше 1, я закрываю порты, применяя метод ondiscoonect. Этот метод очищает объекты и закрывает игровой порт. Несмотря на то, что код говорит, что порт закрыт, он не совсем закрыт. После первого создания игры, если другой пользователь хочет создать новую игру, он получает сообщение об ошибке, что порты уже используются. (Java.net.BindException). Трассировка стека приведена ниже;

INFO: server (0.0.0.0:20051) has been shutdown
Apr 22, 2011 9:20:09 AM org.xsocket.connection.IoAcceptor <init>
WARNING: could not bind server to 0.0.0.0/0.0.0.0:20051. Reason: java.net.BindException: Address already in use
        at sun.nio.ch.Net.bind(Native Method)
        at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:119)
        at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:59)
        at org.xsocket.connection.IoAcceptor.<init>(IoAcceptor.java:117)
        at org.xsocket.connection.IoAcceptor.<init>(IoAcceptor.java:94)
        at org.xsocket.connection.IoProvider.createAcceptor(IoProvider.java:453)
        at org.xsocket.connection.Server.<init>(Server.java:492)
        at org.xsocket.connection.Server.<init>(Server.java:169)
        at           .engine.communication.Game.closeGame(Game.java:246)
        at           .engine.communication.Game.disconnect(Game.java:209)
        at           .engine.communication.Lounge.disconnect(Lounge.java:238)
        at           .engine.Engine.disconnect(Engine.java:102)
        at .engine.communication.gameSocketDataHandler.onDisconnect(gameSocketDataHandler.java:235)
        at org.xsocket.connection.HandlerAdapter.performOnDisconnect(HandlerAdapter.java:334)
        at org.xsocket.connection.HandlerAdapter.access$300(HandlerAdapter.java:42)
        at org.xsocket.connection.HandlerAdapter$PerformOnDisconnectTask.run(HandlerAdapter.java:317)
        at org.xsocket.SerializedTaskQueue.performPendingTasks(SerializedTaskQueue.java:161)
        at org.xsocket.SerializedTaskQueue.access$100(SerializedTaskQueue.java:40)
        at org.xsocket.SerializedTaskQueue$MultithreadedTaskProcessor.run(SerializedTaskQueue.java:189)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
        at java.lang.Thread.run(Thread.java:619)

Как видно из трассировки, исключение выдается в строке кода 246 класса Game. Код этого метода приведен ниже;

public void closeGame() {
    try {

        server.close();
        System.out.println("Opened?"+server.isOpen());
        LoungeManager.removeGame(loungeId, gameId);
    } catch (Exception ex) {
        String err = "Game.closeGame:" + ex.getMessage();
        err += logGame.exceptionTrace(ex);
        logGame.appendLog(err, Severity.FATAL);
    }
}

Спасибо за вашу помощь и еще раз спасибо сайт stackoverflow. Вопрос можно сказать немного длиннее, но я хочу, чтобы я был понятен. Я жду вашего совета.

kingspeech

Ответы [ 2 ]

2 голосов
/ 22 апреля 2011

У меня такие же проблемы в проекте c ++ в linux.

Единственное, что мне помогло, это

setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1)

до привязки

Обновление:

Это не ошибка, это особенность

2 голосов
/ 22 апреля 2011

FreeBSD довольно хорошо закрывает сокеты;Я не думаю, что проблема в операционной системе.

Когда вы настраиваете сокет своего сервера, вызовите setReuseAddress (true), прежде чем связывать.Операционная система должна сохранять предыдущий кортеж {srcip, srcport, dstip, dstport} вне срока действия дескриптора сокета сервера в вашем процессе;опция повторного использования адреса позволяет вам установить другой сокет сервера, пока он присутствует.

...