0

我对套接字重新连接有很大的问题。我有用 Delphi 编写的套接字服务器,但通信应用程序必须在 java (android) 中。问题是我的服务器停止了几分钟 - 例如重新启动或类似的东西。在这种情况下,java(android)客户端迷恋(因错误而停止)本身。我在远程服务中编写客户端,它在两个线程中工作。第一个用于连接或重新连接:

thrd1 = new Thread(new Runnable() {
    public void run() {
        while (!Thread.interrupted()) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
            }
            if (sock==null)
            try {
                sock = new Socket("address", 5000);
                r = new BufferedReader(new InputStreamReader(sock.getInputStream()));
                out = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
            } catch (UnknownHostException e) {
            } catch (IOException e) {
        }
    }

第二个是定期向服务器发送数据:

            thrd2 = new Thread(new Runnable() {
                public void run() {
                    while (!Thread.interrupted()) {
                        try {
                            if (sock != null) {
                                out.write("TEST DATA\n");
                                out.flush();
                                try {
                                    Thread.sleep(1000);
                                } catch (InterruptedException e) {

                                    e.printStackTrace();
                                }
                            } 

                        } catch (IOException e) {
                            sock = null;
                            out = null;
                            r = null;
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e1) {
                            }
                        }
                    }
                }
            });

为什么我的应用程序在失去连接后确实死了?服务器长时间不工作后如何正确重新连接(换句话说:如何等待启动服务器并在启动后立即连接。

感谢 Lois,我改进了我的代码,现在它看起来像:

thrd2 = new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
    try {
        if (sock != null) {
            out.write("TEST DATA\n");
            out.flush();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } 
        //if sock is null wait 300ms
        else {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                 e.printStackTrace();
            }
        }
    } catch (IOException e) {
        try {
            sock=null;
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
             e.printStackTrace();
        }
    }
}
}

thrd1 = new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
    try {
        Thread.sleep(100);
    } catch (InterruptedException e1) {

    }
    if (sock==null)
    try {
        sock = new Socket();
        sock.connect(new InetSocketAddress(
                address, 5000), 300);
        r = new BufferedReader(new InputStreamReader(
                sock.getInputStream()));
        out = new BufferedWriter(
                new OutputStreamWriter(sock
                        .getOutputStream()));
        if ((thrd2!=null)&&(!thrd2.isAlive()))
        thrd2.start();
    } catch (UnknownHostException e) {
         e.printStackTrace();

    } catch (IOException e) {
         e.printStackTrace();
    }
}
;
}
});
if ((thrd1!=null)&&(!thrd1.isAlive())) thrd1.start();

应用程序没有崩溃,但我得到了奇怪的通信过程。服务器为我提供信息,服务器唤醒时两次或更多(取决于断开服务器的时间)尝试从套接字客户端启动(初始化)连接?我认为这是不正确的 - 在服务器唤醒之后开始连接必须只有一次尝试(如果它成功)?顺便说一句:从这个线程我知道每个catch都必须有实现——我的意思是当子句“try”在异常之后去那里时要执行一些代码(不是空代码)。但是当我只想保护我的应用程序免受错误但对这种情况的反应不需要我的代码中的任何特殊反应时,我必须放在那里?

下面的一些日志描述了这种情况(对不起,我在第一篇帖子中忘记了这个线程主要活动是 com.example.aj.siec:

12-09 10:09:29.750: W/System.err(1799): java.net.SocketTimeoutException: Connection timed out
12-09 10:09:29.750: W/System.err(1799):     at org.apache.harmony.luni.platform.OSNetworkSystem.connect(Native Method)
12-09 10:09:29.750: W/System.err(1799):     at dalvik.system.BlockGuard$WrappedNetworkSystem.connect(BlockGuard.java:357)
12-09 10:09:29.750: W/System.err(1799):     at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:204)
12-09 10:09:29.750: W/System.err(1799):     at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:437)
12-09 10:09:29.750: W/System.err(1799):     at java.net.Socket.connect(Socket.java:983)
12-09 10:09:29.750: W/System.err(1799):     at com.example.aj.siec.MainActivity$1$2.run(MainActivity.java:117)
12-09 10:09:29.750: W/System.err(1799):     at java.lang.Thread.run(Thread.java:1019)
12-09 10:09:30.830: W/System.err(1799): java.net.SocketTimeoutException: Connection timed out
12-09 10:09:30.830: W/System.err(1799):     at org.apache.harmony.luni.platform.OSNetworkSystem.connect(Native Method)
12-09 10:09:30.830: W/System.err(1799):     at dalvik.system.BlockGuard$WrappedNetworkSystem.connect(BlockGuard.java:357)
12-09 10:09:30.830: W/System.err(1799):     at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:204)
12-09 10:09:30.830: W/System.err(1799):     at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:437)
12-09 10:09:30.830: W/System.err(1799):     at java.net.Socket.connect(Socket.java:983)
12-09 10:09:30.830: W/System.err(1799):     at com.example.aj.siec.MainActivity$1$2.run(MainActivity.java:117)
12-09 10:09:30.830: W/System.err(1799):     at java.lang.Thread.run(Thread.java:1019)
12-09 10:09:31.800: W/System.err(1799): java.net.SocketTimeoutException: Connection timed out
12-09 10:09:31.800: W/System.err(1799):     at org.apache.harmony.luni.platform.OSNetworkSystem.connect(Native Method)
12-09 10:09:31.800: W/System.err(1799):     at dalvik.system.BlockGuard$WrappedNetworkSystem.connect(BlockGuard.java:357)
12-09 10:09:31.800: W/System.err(1799):     at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:204)
12-09 10:09:31.800: W/System.err(1799):     at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:437)
12-09 10:09:31.800: W/System.err(1799):     at java.net.Socket.connect(Socket.java:983)
12-09 10:09:31.800: W/System.err(1799):     at com.example.aj.siec.MainActivity$1$2.run(MainActivity.java:117)
12-09 10:09:31.800: W/System.err(1799):     at java.lang.Thread.run(Thread.java:1019)

谢谢您的回答 - 解决这个问题对我来说真的很重要!

问候

阿尔蒂克

4

1 回答 1

1

您没有显示堆栈跟踪,因此我将指出上面代码中的一些直接错误:

  • 您没有处理连接丢失并将套接字重置为空,因此不会尝试重新连接
  • 您应该只thrd2在成功连接后开始thrd1
  • thrd2当 socket 为 null 时,不要点击,sleep()并且会持续循环消耗 100% 的 CPU 时间。

问候。

于 2012-12-09T00:45:59.460 回答