Android, проблемы с SocketAddress и сокетами.Обратный поиск? - PullRequest
3 голосов
/ 25 августа 2011

У меня проблема с Android. Я пытаюсь подключиться к серверу с прокси безуспешно.

У меня есть этот код, который отлично работает на обычной Java. Он только определяет прокси-сервер и создает сокет, который будет подключаться к Google с этим прокси. Он отправляет простой запрос GET и затем показывает ответ.

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketAddress;

public class Main {

    public static void main(String[] args) {
        try{
            //create the proxy info
            SocketAddress socketAddress = new InetSocketAddress("78.137.18.67" , 8364);
            Proxy proxy = new Proxy(Proxy.Type.SOCKS, socketAddress);

            // create the socket with the proxy
            Socket socket = new Socket(proxy);

            // connect to some address and send/receive data
            socket.connect(new InetSocketAddress("www.google.com", 80));
            socket.getOutputStream().write("GET /index.html HTTP/1.1\r\nHost: www.google.com\r\n\r\n".getBytes("UTF-8"));
            byte result[] = new byte[1024];
            socket.getInputStream().read(result);
            socket.close();
            System.out.println(new String(result));
        }catch(Exception e){
            e.printStackTrace();
        }

    }
}

Проблема с android, с подобным кодом, заключается в том, что InetSocketAddress делает что-то странное. Кажется, что он выполняет обратный поиск данного ip, и затем сокет, созданный с помощью прокси, пытается соединиться с разрешенным именем хоста, в данном случае это 78-137-18-67.dynamic-pool.mclaut.net.

Это не будет проблемой (за исключением производительности), если сокет сможет преобразовать имя хоста обратно в IP-адрес. Дело в том, что это имя хоста не может быть разрешено в IP-адрес с моим подключением к Интернету (я не знаю, могут ли другие сделать). Таким образом, обратный поиск работает нормально, но при нормальном поиске происходит сбой, поэтому, когда сокет пытается подключиться через прокси, возникает следующее исключение:

08-25 19:26:46.332: ERROR/Microlog(3526): 40274 SocketConnection

[ОШИБКА] Ошибка при установлении соединения java.net.SocketException: SOCKS Ошибка подключения: java.net.UnknownHostException: 78-137-18-67.dynamic-pool.mclaut.net

Итак, вопрос в том, почему он пытается соединиться с именем хоста, если я дал IP-адрес? Есть ли способ избежать этого поиска? Я попытался с createUnresolved из InetSocketAddress, но в этом случае сокет зависает при подключении.

Не является ли трата времени, подключения к Интернету и т. Д. Обратным поиском DNS для получения имени хоста (если оно есть), а позже, когда сокету необходимо подключиться, снова разрешите хост по IP-адресу?

ПРИМЕЧАНИЕ: этот код является примером, настоящее приложение не выполняет http-запрос таким образом. Используются двоичные пакеты данных.

Ответы [ 3 ]

1 голос
/ 26 августа 2011

Чтобы предотвратить обратный поиск, вы можете создать InetAddress с getByAddress(byte[]).

Затем передайте экземпляр InetAddress в конструктор InetSocketAddress.

В качестве альтернативы используйте заводской метод InetSocketAddress.createUnresolved(String,int)

0 голосов
/ 09 апреля 2016

В Android вы должны делать все с фоновым процессом, чтобы вы не писали код для сокета непосредственно в методе onCreate, вы должны делать это в фоновом режиме, чтобы ваш пользовательский интерфейс не зависал примерно так

new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            client = new Socket(ipaddress, port);
                            printwriter = new PrintWriter(client.getOutputStream(), true);
                            InputStream is = client.getInputStream();
                            printwriter.write(msg);
                            printwriter.flush();

                            byte[] buffer = new byte[2046];
                            int read;

                            while ((read = is.read(buffer)) != -1) {
                                final String output = new String(buffer, 0, read);
                                );
                                        printwriter.close();
                                    }
                                });
                            }


                            Log.e("message", "message send");
                        } catch (UnknownHostException e2) {
                            e2.printStackTrace();
                        } catch (IOException e1) {
                            e1.printStackTrace();
                            Log.d("Time out", "Time");

                        }
0 голосов
/ 25 августа 2011

Да, похоже, что конкретный конструктор InetSocketAddress выполняет обратный поиск DNS: http://mailinglists.945824.n3.nabble.com/Android-and-reverse-DNS-lookup-issues-td3011461.html

Кроме того, похоже, что это больше не происходит в Android 2.3.4.

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