2011-03-22 4 views
6

연결할 서버 목록이있는 GUI가 있습니다. 사용자가 서버를 클릭하면 연결됩니다. 사용자가 두 번째 서버를 클릭하면 첫 번째 서버를 연결 해제하고 두 번째 서버에 연결합니다. 프로그램이 다른 작업을 수행 할 수 있도록 새 연결이 각각 새 스레드에서 실행됩니다.연결 소켓을 중단하십시오

그러나 첫 번째 서버가 여전히 연결되어있는 상태에서 두 번째 서버를 클릭하면 두 개의 동시 연결이 있습니다.

Socket socket = new Socket(); 
socket.connect(socketAddress, connectTimeout); 

내가 어쩌면 Thread.currentThread().interrupt(); 작동 것이라고 생각하지만,하지 않았다 :

I)이이를 사용하여 연결하고, (연결 해요 블록은 라인입니다.

코드를 약간 수정하여 첫 번째 연결을 계속 만들지 만 곧바로 종료해야합니까? 또는 실제로 연결 메서드를 중단하는 방법이 있습니다.

답변

2

블로킹 소켓 구현을 사용하는 경우 스레드를 인터럽트해도 소켓 연결이 '취소'되거나 중단되지 않습니다. 'blocking call'을 벗어나는 유일한 방법은 소켓을 '닫는 것'입니다. 사용자가 두 번째 서버에 연결을 시도 할 때 소켓을 닫고 리소스를 정리하는 Runnable 작업 (예 : cancel)에 메소드를 노출 할 수 있습니다.

블로킹 호출을하는 스레드를 방해 할 때 look at my throwaway attempt을 사용할 수 있습니다.

+0

내가 socket.close() 시도, 그것은 소켓이 null 말한다 .. 그러나 그것이 있어야 유효한 (그러나 연결되지 않은) Socket 객체입니다. disconnect()라는 메서드 내에서 같은 Runnable 클래스에서 close()를 호출하고 있는데, 다른 스레드에서 호출 한 이유는 무엇입니까? close()는 소켓에서 다른 스레드에서 직접 호출해야합니까? – Matt

+0

@Matt : 코드를 보지 않고 말할 수는 없지만 확인하고 싶었습니다. 소켓 변수와 인스턴스 변수 또는 메소드가 하나입니까? Runnable 태스크의'socket' 속성이 null이 아닌 것은 확실합니까? 그렇다면, 태스크 객체에서 소켓 변수'volatile'을 시도하고 다시 시도 할 수 있습니까? 그것은 여전히 ​​실패합니까? –

1

대신 비 차단 소켓을 사용할 수 있습니까? 저는 Java 전문가가 아니지만 SocketChannel이 비 블로킹 소켓 클래스 인 것처럼 보입니다.

// Create a non-blocking socket and check for connections 
try { 
    // Create a non-blocking socket channel on port 80 
    SocketChannel sChannel = createSocketChannel("hostname.com", 80); 

    // Before the socket is usable, the connection must be completed 
    // by calling finishConnect(), which is non-blocking 
    while (!sChannel.finishConnect()) { 
     // Do something else 
    } 
    // Socket channel is now ready to use 
} catch (IOException e) { 
} 

여기에서 촬영 : 당신이 취소 구제 할 필요가 일부 공유 알림을 확인할 수 있습니다 while 루프 내부 http://www.exampledepot.com/egs/java.nio/NbClientSocket.html

의 SocketChannel에 폐쇄 여기

은 예입니다 네가 간다.

1

제안 된 답변을 시도했지만 나에게 도움이되지 않았습니다. 그래서 내가 한 것은 연결 시간 제한을 10 초로 설정하는 대신 연결 시간 제한을 2 초로 연속 5 회 연결하려고했습니다. 또한 글로벌 변수 boolean cancelConnection이 선언되었습니다.

시간 초과 예외가 발생할 때마다 cancelConnection 값을 기반으로 루프를 중단하거나 계속할 수 있습니다. 여기

내가 쓰고 있어요 안드로이드 응용 프로그램에서 코드입니다 :

try { 
    SocketAddress socketaddres = new InetSocketAddress(server.ip,server.port); 
    int max=5; 
    for (int i = 1; i<=max; i++) { 
     try { 
      socket = new Socket(); 
      socket.connect(socketaddres, 2000); 
      break; 
     } catch (Exception e) { 
      Log.d(TAG, "attempt "+i+ " failed"); 
      if (cancelConnection) { 
       Log.d(TAG, "cancelling connection"); 
       throw new Exception(); 
      } else if (i==max) { 
       throw new Exception(); 
      } 
     } 
    } 
} catch (Exception e) { 
    if (cancelConnection) { 
      // Do whatever you would do after connection was canceled. 
    } else { 
      // Do whatever you would do after connection error or timeout 
    } 
} 
관련 문제