Android Network Programming: IoExceptions e StackOverflowerRor
-
27-09-2019 - |
Pergunta
No meu aplicativo Android, tento me conectar a uma porta em um servidor local para obter alguns pacotes. Eu entrei para codificar em algumas tentativas e capturas, mas com o seguinte código:
address = "192.168.175.82";
public void run() {
try {
smtpSocket = new Socket(address, 60001);
os = new DataOutputStream(smtpSocket.getOutputStream());
is = new DataInputStream(smtpSocket.getInputStream());
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + address);
run();
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: " + address);
run();
} catch (Exception e) {
System.out.println("retry");
run();
}
Se o servidor não estiver ativado, obviamente, eu obtive a ioexception algumas vezes (por exemplo, algumas centenas de vezes) antes de receber um erro de estilagem de pilha e o aplicativo trava.
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): java.lang.StackOverflowError
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.util.Hashtable.get(Hashtable.java:282)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.util.Properties.getProperty(Properties.java:177)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.lang.System.getProperty(System.java:440)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.lang.System.getProperty(System.java:412)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.lang.Boolean.getBoolean(Boolean.java:174)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at org.apache.harmony.luni.net.NetUtil$Action.run(NetUtil.java:89)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at org.apache.harmony.luni.net.NetUtil$Action.run(NetUtil.java:80)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.security.AccessController.doPrivilegedImpl(AccessController.java:264)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.security.AccessController.doPrivileged(AccessController.java:84)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at org.apache.harmony.luni.net.NetUtil.preferIPv6Addresses(NetUtil.java:51)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at org.apache.harmony.luni.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.net.Socket.startupSocket(Socket.java:777)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.net.Socket.tryAllAddresses(Socket.java:192)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.net.Socket.<init>(Socket.java:256)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at java.net.Socket.<init>(Socket.java:220)
01-20 22:21:32.526: ERROR/AndroidRuntime(5678): at com.example.sockets.ReadSocket.run(ReadSocket.java:83)
Alguém poderia me apontar na direção certa de como fazer isso funcionar? Talvez eu deva testar a conexão primeiro de alguma forma (se sim, por favor, diga como?) Obrigado
Chris
Solução
Para iniciantes, solte a chamada recursiva. Isso se livrará do transbordamento da pilha. Substitua -o por um loop e durma em cada iteração sem êxito
public void run() {
boolean connected = false;
while(!connected)
{
try {
smtpSocket = new Socket(address, 60001);
os = new DataOutputStream(smtpSocket.getOutputStream());
is = new DataInputStream(smtpSocket.getInputStream());
connected = true;
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + address);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: " + address);
} catch (Exception e) {
System.out.println("retry");
}
if (!connected)
Thread.sleep(1000)
}
}
Outras dicas
Podes tentar isConnected()
e isBound()
No seu soquete para verificar se você está conectado ou não antes de tentar obter um inseto.