1

所以我在 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();
        }
    }
}

所以这就是问题所在……我点击了智能手机上的主页按钮,这使程序暂停。我再次启动程序,它在活动中调用恢复函数,进而启动重新连接过程。尝试连接,我没有收到任何错误。但是,我的 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 做类似的事情还是必须做?谢谢您的帮助!

4

2 回答 2

3

根据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));
}

(请放置大括号:-))

于 2013-03-13T21:20:07.307 回答
1

需要记住的是 isConnected() 方法对于检测远程端何时关闭连接不是很可靠,(这里是一个例子)

您必须通过读取或写入相关的输入/输出流来解决这个问题。

尝试使用 PrintWriter.checkError(),一旦客户端无法再连接到服务器,它将返回 true 。

于 2013-03-13T21:23:04.547 回答