开发者

Socket does not throw an exception though he can’t connect

I'm trying to connect a socket to an non-existent server, and I really don't understand why an exception is not being raised.

Here is my code:

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");
        }
    }
}

I also tried with my own IP address while running Wireshark, and I first get [SYN] from Android to my computer and then [RST, ACK] from my computer to Android (because nothing is listening at this port), but I still do not get an exception on Android.

Also I’m testing on a physical phone (Nexus S), and I do have the internet permission in my Manifest.

Why aren't I getting an Exception?

Edi开发者_高级运维t:

More precisely, the output I get is

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

(and not Exception)


In the Socket constructor, it's thrown when the IP address of the host can't be determined, so I assume that because you aren't passing a hostname which needs resolution, a different exception would be getting thrown instead. I believe the exception actually comes from the URL class or such which does the resolution, and from nowhere else.

The connect(..) method should throw an exception but doesn't appear to, as you say.

Edit: apparently Android (some versions) doesn't work properly here, so it's probably a bug: http://code.google.com/p/android/issues/detail?id=6144. It doesn't look like the link refers to the emulator as I had thought.


There are a variety of things that can cause a socket connect to fail with an exception.

However, if the SYN message that the TCP protocol sends to start the connection process is

  • blocked by a firewall,
  • routed through a borked network, or
  • routed to some endpoint that doesn't respond,

then TCP stack on the initiating machine will just retry, and retry. If you have a connect timeout set, you will eventually get an exception, but it could take a long time.


The fact that it works on the Android emulator and not on the real device simply means that they are implemented or configured differently. (For instance, they may have different default connect timeouts ... of the emulator may be designed to give connection refused in that scenario.)

The bottom line is that you need to make your code work on the real device. Figure out the best way to make your device set a connect timeout, and check that that works when talking to the non-existent server.


Your try catch code doesn't catch IO Exceptions. Try something like this

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜