Java重新启动套接字

时间:2015-06-09 17:55:48

标签: java multithreading sockets

我有一个套接字,它在一个线程中初始化,这是我的代码。

public class Receiver extends Thread {

        public static boolean connect() {
            boolean result;
            try {
                client = new Socket(serverIPString,Integer.parseInt(serverPortString));
                result = true;
            } catch (IOException e) {
                result = false;
                WriteExceptions.writeToFile(e);
            }
            return result;
        }

        public void run() {

            while (!connect()) {
                // try to connect every 30 seconds
                try {
                    TimeUnit.SECONDS.sleep(30);         
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                }
            }
            initializeThreads();

        }

        public static void initializeThreads() {

            try {
                System.out.println("initializeThreads...");
                // create new thread pool with four threads
                application = Executors.newCachedThreadPool();
                // create ArrayBlockQueueSync to store ints
                sharedLocation = new ArrayBlockQueueSync();
                // execute tasks
                t1 = application.submit(new Reader(client.getInputStream(),sharedLocation));
                t2 = application.submit(new Writer(client.getOutputStream(),sharedLocation));

                sd = Executors.newScheduledThreadPool(2);

                t3 = sd.scheduleAtFixedRate(new LinkAlive(sharedLocation),15000, 5 * 60 * 1000, TimeUnit.MILLISECONDS);
                t4 = sd.scheduleAtFixedRate(new DBSync(sharedLocation), 5 * 60 * 1000, 24 * 60 * 60 * 1000, TimeUnit.MILLISECONDS);

            } catch (IOException e) {
                 WriteExceptions.writeToFile(e);
            }

        }

        public static void disconnect(){
            try {
                client.close();
                System.out.println("Close Socket");
                shutdownAndAwaitTermination();
            } catch (IOException e) {
                e.printStackTrace();
                WriteExceptions.writeToFile(e);
            }
        }

        public static void shutdownAndAwaitTermination() {      
            t1.cancel(true);
            t2.cancel(true);
            t3.cancel(true);
            t4.cancel(true);
            application.shutdown(); 
            sd.shutdown(); 
            try {
                if (!application.awaitTermination(60, TimeUnit.SECONDS)) {
                    application.shutdownNow(); 
                    if (!application.awaitTermination(60, TimeUnit.SECONDS))
                        System.err.println("Pool did not terminate");
                 }
                 if (!sd.awaitTermination(60, TimeUnit.SECONDS)) {
                    sd.shutdownNow();
                     if (!sd.awaitTermination(60, TimeUnit.SECONDS))
                         System.err.println("Pool did not terminate");
                 }
            } catch (InterruptedException ie) {
                WriteExceptions.writeToFile(ie);
                application.shutdownNow();
                sd.shutdownNow();   
            }
            client = null;
            reconnect();
        }

        public static void reconnect(){
            try {
                Messages.writeStringToFile("Start the countdown","RECS");
                for(int i=1; i<=60; i++){           
                    TimeUnit.SECONDS.sleep(1);
                    Messages.writeStringToFile(i+" seconds","REC");
                }
                Messages.writeStringToFile("End the countdown","RECE");

                // try to reconnect
                while (!connect()) {
                    Messages.writeStringToFile("Try to connect.","RECT");
                    // try to connect every 60 seconds
                    try {
                        TimeUnit.SECONDS.sleep(60);
                    } catch (InterruptedException ex) {
                        Thread.currentThread().interrupt();
                    }
                }
                initializeThreads();
            } catch (Exception e) {
                WriteExceptions.writeToFile(e);
            }
        }
}

此套接字用于与其他程序通信。我有4个runnables,Reader正在读取来自套接字的传入数据,另外3个是在socket上写的,但是在Writer runnable上,当我收到一个特殊数据时,就是说我正在通信的另一个程序将要关闭,所以我必须重启我的,这是代码。

public class Writer implements Runnable {
    @Override
    public void run() {
        ....
        // disconnect
        Receiver.disconnect();
        ....
    }
}

当断开呼叫时,我得到一系列例外,第一个是:

java.net.SocketException: Socket closed
    at java.net.SocketInputStream.read(SocketInputStream.java:203)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.net.SocketInputStream.read(SocketInputStream.java:223)
    at sockets.Reader.deserialize(Reader.java:74)
    at sockets.Reader.run(Reader.java:36)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

第二个例外是:

java.lang.InterruptedException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2067)
    at java.util.concurrent.ThreadPoolExecutor.awaitTermination(ThreadPoolExecutor.java:1465)
    at sockets.Receiver.shutdownAndAwaitTermination(Receiver.java:143)
    at sockets.Receiver.disconnect(Receiver.java:124)
    at sockets.Writer.run(Writer.java:97)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

最后的例外是:

java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at java.lang.Thread.sleep(Thread.java:340)
    at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
    at sockets.Receiver.reconnect(Receiver.java:181)
    at sockets.Receiver.shutdownAndAwaitTermination(Receiver.java:170)
    at sockets.Receiver.disconnect(Receiver.java:124)
    at sockets.Writer.run(Writer.java:97)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

之后程序什么也没做。也许我做了糟糕的设计或错误的方法。抱歉我的英文。

1 个答案:

答案 0 :(得分:3)

尝试在客户端关闭输入和输出流。

client = new Socket(serverIPString,Integer.parseInt(serverPortString));
InputStream in = client.getInputStream();
OutputStream out = client.getOutPutStream();

//Do your work with input and output stream.....

in.close();
out.close();