Прервите соединительный разъем - PullRequest
8 голосов
/ 22 марта 2011

У меня есть графический интерфейс со списком серверов для подключения. Если пользователь нажимает на сервер, он подключается к нему. Если пользователь щелкнет второй сервер, он отключит первый и подключится ко второму. Каждое новое соединение запускается в новом потоке, чтобы программа могла выполнять другие задачи.

Однако, если пользователь нажимает второй сервер, пока первый еще подключается, существует два одновременных подключения.

Я подключаюсь, используя это, и connect () - это строка, которая блокирует:

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

Я думал, может быть, Thread.currentThread().interrupt(); сработает, но не смог.

Должен ли я немного реструктурировать свой код, чтобы он продолжал устанавливать первое соединение, но сразу же закрывал его? Или есть способ прервать метод соединения.

Ответы [ 3 ]

2 голосов
/ 22 марта 2011

Если вы используете реализацию сокета с блокировкой, прерывание потока не будет «отменять» или прерывать соединение с сокетом.Единственный способ выйти из «блокирующего вызова» - это «закрыть» сокет.Вы можете предоставить метод для ваших задач Runnable (например, cancel), который закрывает сокет и очищает ресурсы, когда пользователь пытается подключиться ко второму серверу.

Если вы хотите, вы можете иметь посмотрите на мою одноразовую попытку прерывать потоки, которые делают блокирующие вызовы.

1 голос
/ 17 июня 2012

Я попробовал предложенные ответы, но у меня ничего не получалось.Поэтому я вместо установки таймаута соединения на 10 секунд пытаюсь подключиться 5 раз подряд с таймаутом соединения 2 секунды.У меня также есть глобальная переменная boolean cancelConnection, объявленная.

Каждый раз, когда выдается исключение тайм-аута, я могу вырваться из цикла или продолжить цикл на основе значения cancelConnection.

Вот фрагмент кода из приложения для Android, которое я пишу:

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
    }
}
1 голос
/ 22 марта 2011

Можете ли вы вместо этого использовать неблокирующую розетку?Я не очень разбираюсь в 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) {
}

Взято отсюда: http://www.exampledepot.com/egs/java.nio/NbClientSocket.html

Внутри цикла while вы можете проверить наличие общего уведомления, которое необходимо отменить и выручить, закрыв SocketChannel по ходу работы.

...