虽然Socket无法连接,但它不会抛出exception

我正在尝试将套接字连接到不存在的服务器,我真的不明白为什么没有引发exception。

这是我的代码:

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

我在运行Wireshark时也尝试使用自己的IP地址,我首先从Android到我的计算机[SYN] ,然后从我的电脑到Android的[RST, ACK] (因为没有什么东西在这个端口监听),但我仍然这样做在Android上没有例外。

此外,我正在使用物理手机(Nexus S)进行测试,并且我在我的Manifest中拥有互联网许可。

为什么我没有得到Exception

编辑:

更确切地说,我得到的输出是

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

(而不是Exception

在Socket构造函数中,当无法确定主机的IP地址时抛出它,因此我假设因为您没有传递需要解析的主机名,所以会抛出另一个exception。 我认为exception实际上来自URL类或其他解决方案,而不是其他任何地方。

正如你所说,connect(..)方法抛出一个exception,但似乎没有。

编辑:显然Android(某些版本)在这里无法正常工作,所以它可能是一个错误: http : //code.google.com/p/android/issues/detail ?id = 6144 。 它看起来并不像我想象的那样链接指向模拟器。

有许多事情可能导致套接字连接失败并出现exception。

但是,如果TCP协议发送的SYN消息启动连接过程是

  • 被防火墙阻挡,
  • 通过一个borked网络路由,或
  • 路由到某个没有响应的端点,

然后启动机器上的TCP堆栈将重试,然后重试。 如果设置了连接超时,最终会出现exception,但可能需要很长时间。


它在Android模拟器上工作而不在真实设备上的事实只是意味着它们的实现或配置不同。 (例如,它们可能具有不同的默认连接超时…模拟器可能被设计为在该场景中拒绝连接。)

最重要的是,您需要使代码在真实设备上运行。 找出使您的设备设置连接超时的最佳方法,并在与不存在的服务器通信时检查它是否有效。

您的try catch代码不会捕获IOexception。 尝试这样的事情

 try { // to get the ip address of the server by the name
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); }