Java Socket的应用程序随机停止

时间:2009-11-04 04:13:06

标签: java multithreading sockets

服务器

public void run () {

 Socket serversocket = new ServerSocket(port);
 while(true) {
   new Thread(new ServerThread(serverSocket.accept())).start();
 }
}
//serverSocket.close(); etc

ServerThread

public void run() {
 BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

 String input;

 while(true) {
   input = in.readLine();
   new Thread(new RequestThread(clientSocket, input)).start();
 }
}
//close sockets etc in.close() clientSocket.close();

请求线程

public void run() { 
 //input was passed from constructor
 String output = new SomeProtocol(input);

 if(output == null)
  break;
 //true for auto flush
 PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
 out.println(output);
}//closing out seems to also close the socket, so opted to not to close it, maybe this is the one giving me trouble?

监视器

public class ServerMonitor implements Runnable{
    private ServerThread server;
    private LoggingClass log = LoggingClass .getInstance();
    private int heartbeat = 0;

    public ServerMonitor(ServerThread server) {
        this.server = server;
    }

    public boolean checkFile() {
        File file = new File("cmd//in//shutdown.txt");
        return file.exists();
    }

    public void run() {

        log.logToFile("Server monitor running");

        while (true) {
            incHeartbeat();
            if (checkFile()) {
                log.logToFile("Shutting down server");
                break;
            }
            writeStatus();
            this.delay(5000);
        }

        log.logToFile("Server monitor stopped");
    }

    public void delay(long delay) {
        try {
            wait(delay);
        } catch (InterruptedException e) {
            log.logToFile("Monitor sleep error");
            e.printStackTrace();
        }
    }

    public void writeStatus() {
        try {
            BufferedWriter out = new BufferedWriter(new FileWriter(
                    "sys//status//status.txt"));
            out.write("Start date:" + log.getStartDate());
            out.newLine();
            out.write("Current date:" + log.getTimestamp("yyyy-MMM-dd k:mm:ss"));
            out.newLine();
            out.write("Heartbeat:" + getHeartbeat());
            out.newLine();
            out.write("Cimd in:" + log.getCimdIn());
            out.newLine();
            out.write("Cimd out:" + log.getCimdOut());
            out.newLine();
            out.write("Keep alive:" + log.getCimdKeepAlive());
            out.newLine();
            out.write("HTTP in:" + log.getNumHTTPIn());
            out.newLine();
            out.write("HTTP out:" + log.getNumHTTPOut());
            out.newLine();
            out.close();

        } catch (Exception e) {
            log.logToFile("Write status error");
            e.printStackTrace();
        }
    }

    public int getHeartbeat() {
        return heartbeat;
    }

    public synchronized void incHeartbeat() {
        heartbeat++;
    }
}

这是我的应用程序的粗略骨架。我遇到了麻烦,因为有时它会在没有任何错误的情况下停止。我怀疑这可能是因为插座但是我不太确定所以你们中的任何人都有任何想法?感谢。


添加了监控服务器线程的类

>How do I know that it doesn't work

心跳不再增加

3 个答案:

答案 0 :(得分:1)

您的内存/线程可能已用完

你碰巧有这样的高级异常处理:

public static void main( String ... args ) {
    try {
        // lots of code ... 
    } catch( Exception e ) {}
}

如果是这样,你必须至少记录你忽略的错误。

这就是我想到的,因为我手头没有你的源代码。

答案 1 :(得分:0)

你能更好地定义'停止工作'吗?是否停止接受连接;它崩溃了吗?它是否会在处理过程中停止做某事;等?

有一点猜测是我不确定套接字关闭时读卡器会发生什么。我期望发生的是,尝试使用已关闭的套接字调用read行会导致异常,这会停止该线程,并且/或者可能会终止整个应用程序。哪会产生堆栈跟踪等问题。

基本上,除了Oscar所说的主要异常记录之外;你想要登录任何run()方法。 main中的try / catch只捕获主线程抛出的异常;不是其他线程中抛出的那些。

答案 2 :(得分:0)

很难从您发布的伪代码中判断,但如果应用程序挂起(并且没有完全崩溃),我最好的猜测是ServerThread中的in.readLine()阻塞。如果应用程序刚刚关闭,我会查看socket闭包,也许在BufferedReader中检查isReady()。

一般性评论:您可能会产生比此处所需更多的线程。它看起来像是从客户端套接字读取并且对它的写入是连续发生的。如果是这种情况,ServerThread Runnable(我假设它是一个Runnable,因为你将它传递给一个Thread的构造函数)不一定需要生成一个RequestThread。

public class ServerRunnable implements Runnable {
    ...

    public void run() {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

         String input;

         while(true)
         {
           input = in.readLine();
           if(input == null)
           {
               //this means the underlying socket closed
               //log something here or return or whatever
           }

           String output = new SomeProtocol(input);

           if(output == null)
            break;
           //true for auto flush
           PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
           out.println(output);
         }
    }
    ...
}