Сокет не выдает исключение, хотя он не может подключиться - PullRequest
4 голосов
/ 19 апреля 2011

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

Вот мой код:

public class TestSocket extends Activity {
    private static final String TAG = "TestSocket";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BasicThread t = new BasicThread();
        t.start();
    }

    class BasicThread extends Thread {
        @Override
        public void run() {
            Log.d(TAG, "Before");
            try {
                new Socket("42.42.42.42", 12345);
                Log.d(TAG, "Connected");
            } catch (Exception e) {
                Log.d(TAG, "Exception");
            }
            Log.d(TAG, "After");
        }
    }
}

Я также пытался использовать свой собственный IP-адрес при запуске Wireshark, и сначала я получаю [SYN] с Android на мой компьютер, а затем [RST, ACK] с моего компьютера на Android (потому что на этом порте ничего не прослушивается), но я все еще продолжаю не получить исключение на Android.

Также я тестирую на физическом телефоне (Nexus S), и у меня есть разрешение на доступ к Интернету в моем Манифесте.

Почему я не получаю Exception?

Edit:

Точнее, я получаю вывод

D/TestSocket(17745): Before
D/TestSocket(17745): Connected
D/TestSocket(17745): After

(а не Exception)

Ответы [ 3 ]

0 голосов
/ 19 апреля 2011

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

Однако, если сообщение SYN, отправляемое протоколом TCP для запуска процесса подключения, равно

  • заблокирован брандмауэром,
  • маршрутизируется через разветвленную сеть или
  • перенаправлен на конечную точку, которая не отвечает,

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


Тот факт, что он работает на эмуляторе Android, а не на реальном устройстве, просто означает, что они реализованы или настроены по-разному. (Например, у них могут быть разные тайм-ауты подключения по умолчанию ... эмулятора может быть спроектирован так, чтобы в этом сценарии было отказано в соединении.)

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

0 голосов
/ 19 апреля 2011

Ваш код try catch не перехватывает исключения IO.Попробуйте что-то вроде этого

try 
{
    // to get the ip address of the server by the name<br>
    InetAddress ip =InetAddress.getByName("example.com");

    sock= new Socket(ip,Server.PORT);
    ps= new PrintStream(sock.getOutputStream());
    ps.println(" Hi from client");
    DataInputStream is = new 
    DataInputStream(sock.getInputStream());
    System.out.println(is.readLine());
}catch(SocketException e){
    System.out.println("SocketException " + e);
}catch(IOException e){
  System.out.println("IOException " + e);
}
0 голосов
/ 19 апреля 2011

В конструкторе Socket он генерируется, когда IP-адрес хоста не может быть определен, поэтому я предполагаю, что, поскольку вы не передаете имя хоста, для которого требуется разрешение, вместо этого будет выдано другое исключение. Я полагаю, что исключение на самом деле происходит из класса URL или такого, который выполняет разрешение, и из ниоткуда.

Метод connect (..) должен вызвать исключение, но, как вы говорите, не появляется.

Редактировать: очевидно, что Android (некоторые версии) здесь не работает должным образом, так что, вероятно, это ошибка: http://code.google.com/p/android/issues/detail?id=6144. Не похоже, что ссылка относится к эмулятору, как я думал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...