所以我在Windows中使用C ++编程的TCP服务器和JAVA,Android 4.0.4中的客户端。
在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();
}
}
}
所以这就是问题......我点击智能手机上的主页按钮,暂停程序。我再次启动程序并调用活动中的resume函数,然后启动重新连接的过程。尝试连接,我没有错误。但是,我的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 :(得分:2)
根据javadoc,一旦调用构造函数,就建立了连接。
Socket(InetAddress address, int port) Creates a stream socket and connects it to the specified port number at the specified IP address.
当您按下主页按钮时,您的应用程序会进入后台,但不会立即被杀死,因此当您返回应用程序时,comSocket
可能不会为空。在这种情况下,您不再次调用构造函数,因此您没有重新连接到服务器。你应该做的是
if(comSocket == null){
comSocket = new Socket("192.168.0.1",1531);
}else{
comSocket.connect(new InetSocketAddress("192.168.0.1",1531));
}
(请放置大括号:-))
答案 1 :(得分:0)
要记住的是,isConnected()方法对于检测远程端何时关闭连接(here is an example)。
非常不可靠。您必须通过读取或写入相关的输入/输出流来解决这个问题。
尝试使用PrintWriter.checkError(),只要客户端无法再连接到服务器,它就会返回true 。