2011-04-22 6 views
0

FreeBSD에서 xSocket close() 메소드에 관한 문제가 있습니다. Google에서 검색 한 사실에도 불구하고 만족스러운 해결책을 찾지 못했습니다. 조금 자세히 설명해 드리겠습니다.FreeBSD 소켓 닫기 문제

포트를 열어 연결을 수신하는 코드가 있습니다. 나는 이것을 위해 xSocket을 사용한다. 특히 이것은 멀티 플레이어 게임을위한 것이다. 사용자가 게임을 설정하고자 할 때 나는 사용자를위한 포트를 할당하고 사용자는 게임을 만들고 다른 플레이어를 기다릴 수있다. 플레이어가 생성 된 게임의 온라인 플레이어 크기가 1보다 작 으면 플레이어가 웹 브라우저를 닫거나 게임에서 나가면 ondiscoonect 메서드를 적용하여 포트를 닫습니다. 이 메서드는 객체를 지우고 게임 포트를 닫습니다. 코드가 포트가 닫혔다는 사실에도 불구하고 정확히 닫히지 않았습니다. 첫 번째 게임을 만든 후 다른 사용자가 새 게임을 만들고자하면 포트가 이미 사용 중임을 알리는 오류가 발생합니다. (java.net.BindException) 스택 추적은 아래와 같습니다. 이 추적에서 알 수있는 바와 같이, 예외 코드 라인이 방법의 게임 class.The 코드 (246)에서 발생되는

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) 

이하이고;

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에게 감사드립니다. 질문은 조금 오래 말할 수 있지만 나는 이해할 수 있기를 바랍니다. 나는 너의 충고를 기다리고있다.

킹스 픽스

+2

[프로그램의 첫 번째 규칙 : : 그것은 나에게 도움이

있는 유일한 방법은

업데이트 바인딩하기 전에

setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1) 

입니다 항상 당신의 잘못] (http://www.codinghorror.com/blog/2008/03/the-first-rule-of-programming-its-always-your-fault.html) - 'SO_REUSEADDR'을 찾아보십시오 –

+2

나는 FreeBSD 많이. 이 "인기있는 버그"에 대한 참조를 제공 할 수 있습니까? –

+0

도움을 주셔서 감사합니다. – kingspeech

답변

2

FreeBSD는 소켓을 닫으면 꽤 ​​좋습니다. 문제가 운영 체제라고 생각하지 않습니다.

서버 소켓을 설정할 때 바인딩하기 전에 setReuseAddress (true)를 호출하십시오. 운영 체제는 이전 {srcip, srcport, dstip, dstport} 튜플을 프로세스의 서버 소켓 핸들 수명보다 오래 유지해야합니다. 재사용 주소 옵션을 사용하면이 서버가있는 동안 다른 서버 소켓을 설정할 수 있습니다.

2

나는 리눅스의 C++ 프로젝트에서 같은 문제가있다. 그것은,이 기능을 버그가되지