2013-03-13 37 views
0

因此,我在Windows中使用C++编写的TCP服务器以及JAVA,Android 4.0.4中的客户端。重新连接到Android Socket以等待服务器

在Android中,我连这样的:

public boolean sendConnectRequest() 
{ 
    while (isSocketConnected == false) 
    { 
     try { 
      if(comSocket == null) 
      comSocket = new Socket("192.168.0.1",1531); 
      isSocketConnected = comSocket.isConnected(); 
      if (isSocketConnected) { 
       out = comSocket.getOutputStream(); 
       in = comSocket.getInputStream(); 
      } 
      else 
       comSocket.close(); 
     } 
     catch (IOException ex) 
     { 
      Log.e("TCP Error", ex.getLocalizedMessage()); 
     } 
    } 
return true; 
} 

我通常有到服务器的第一个连接上这个代码没有问题。

当我从服务器断开连接,我把这:

public void closeConnection() { 
    if (comSocket != null) 
    { 
     try { 
      comSocket.close(); 
      isSocketConnected = false; 
      if (out != null) 
       out.close(); 
      if (in != null) 
       out.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

因此,这里的问题...我打的智能手机,这使该方案在暂停的主页按钮。我再次启动程序,它会在活动中调用恢复功能,从而启动重新连接过程。连接尝试,我没有得到任何错误。但是,我的Windows服务器没有记录连接。在Windows中,我知道我仍然被阻止在:

SOCKET connectionSocket = accept(tcpNetworkData->socket, (struct sockaddr*)&from, &fromlen); 

我相信这是正常的。当我在Android端处于调试模式时,我注意到它立即从行中返回:comSocket = new Socket(“192.168.0.1”,1531);这应该表明我已建立连接。

如果你跟着我到目前为止...我还应该说,如果我关闭服务器,客户端通过关闭连接并打开一个新的服务器来重置。这次comSocket = new Socket(“192.168.0.1”,1531)不会因为它应该阻塞而且执行继续。这显然是错误的。我认为这是一个资源释放问题,但为什么?随着Winsock的你可以用这行代码解决这个问题:

int so_reuseaddr = TRUE; 
setsockopt(networkData->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&so_reuseaddr,sizeof(so_reuseaddr)); 

你能做到与Android类似的东西或者你有什么打算?感谢您的帮助!

+0

只是为了澄清,你是否在onPause()中重写onResume()和closeConnection()中调用sendConnectRequest()? – crazylpfan 2013-03-13 21:03:39

+0

我正在产卵一个线程,以免阻塞主线程。TCP线程的产生从onResume()开始。在TCP线程中,我实例化一个负责打开和关闭TCP连接的类,并在输出流上轮询输入流和发送消息。在TCP线程中,我在开始轮询过程的TCP连接之后输入一个while循环。要更具体地回答您的问题,在TCP线程上的类中调用sendConnectRequest()。 – user1530101 2013-03-13 21:08:42

+0

只有在comSocket == null的情况下才能重新连接。如果您点击主页按钮,则可能并非如此,因为您的活动可能仍然存在。糟糕的是,没有看到丢失的大括号 – fedepaol 2013-03-13 21:11:11

回答

2

根据javadoc,一旦调用构造函数,就会建立连接。

Socket(InetAddress address, int port) 
     Creates a stream socket and connects it to the specified port number at the specified IP address. 

当您按下home键,您的应用程序进入后台,但它确实当你回到你的申请没有得到当即毙命,所以你comSocket可能是不为空。在这种情况下,你不会再次调用构造函数,因此你没有重新连接到服务器。你应该做的是

if(comSocket == null){ 
     comSocket = new Socket("192.168.0.1",1531); 
}else{ 
    comSocket.connect(new InetSocketAddress("192.168.0.1",1531)); 
} 

(和请请放置大括号:-))

+0

这在服务器端连接中断时有效,但我仍然无法弄清Android客户端终止时发生了什么。 – user1530101 2013-03-14 18:47:41

+0

我在我的回复中写道。当你说“连接尝试,我没有得到任何错误。”,连接并没有真正尝试,因为comSocket不为null,你没有重新连接。 – fedepaol 2013-03-15 01:48:12

0

东西要记住的是,isConnected()方法不是用于检测遥控器时非常可靠方已经关闭了连接,(here is an example)

你必须通过阅读或在相关的输入/输出流写摸不着头脑。

尝试使用PrintWriter.checkError(),这将返回true 只要客户端不能再连接到服务器