FreeBSD socket关闭问题

时间:2011-04-22 06:41:09

标签: java sockets freebsd

我对FreeBSD中的xSocket close()方法有疑问。尽管我在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)

在跟踪中可以看到,在Game类的代码行246中抛出异常。此方法的代码如下;

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 个答案:

答案 0 :(得分:2)

FreeBSD非常擅长关闭套接字;我不认为问题是操作系统。

设置服务器套接字时,请在绑定之前调用setReuseAddress(true)。操作系统必须将先前的{srcip,srcport,dstip,dstport}元组保留在进程中服务器套接字句柄的生命周期之外;重用地址选项允许您在存在时设置另一个服务器套接字。

答案 1 :(得分:2)

我在linux中的c ++项目中遇到了同样的问题。

唯一帮助我的是

setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1)

绑定前

更新

这不是一个错误,它是一个功能