4

私はソケットプログラミングに不慣れで、ソケットを開いてそれに書き込むコードがあります。ソケットのタイムアウトを1分に設定し、特定の条件に達したらソケットを閉じて終了したいと思います。

条件が満たされたときに私のコードがソケットを閉じていません:

@Override
    public void run() {
        Socket socket =null; 
        PrintWriter writer = null; 
        BufferedReader reader = null;
        String host = ServiceProperties.getInstance().getControllerHost();
        String port = "1234;
        String info="";
        // TODO Auto-generated method stub

        try {   
            socket = new Socket(host, Integer.valueOf(port));
            socket.setSoTimeout(60000);
            writer = new PrintWriter(socket.getOutputStream(), true);
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            SampleBean sBean = (SampleBean) (FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("sampleBean"));
            info = ControllerDAO.getInstance().getControllerAndTimeScheduleInfo(sBean.getId());
            writer.println("set TimeSchedule "+ info +" value ["+str+"]");
        }
        catch(UnknownHostException ex) {
            ex.printStackTrace();
        }
        catch(IOException ex) {
            ex.printStackTrace();
        }
        String line="";
        try {
           System.out.println("BEFORE WHILE");
           System.out.println(new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime()));
           while((line= reader.readLine())!=null ) {
               System.out.println(line);
               if(line.contains("OK")){
                  System.out.println("line contains OK ");
                  break;
               }
               try {
                Thread.sleep(5000);
               }
               catch(InterruptedException ex) {
                ex.printStackTrace();
               }
            }
            System.out.println("AFTER WHILE");
            System.out.println(new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime()));
        }
        catch(IOException ex) {
            ex.printStackTrace();
        }
        try {
            writer.close();
            reader.close();
            socket.close();
        }
        catch(IOException ex) {
            ex.printStackTrace();
        }
    }
});
thread.run();

出力:

//"BEFORE WHILE"
// 14:54:55
// prints line
//               //prints empty line
// now it waits for like 40 seconds 
// line contains OK  //condition met here
// breakoutof the loop
    // "AFTER WHILE"
// 14:55:55

なぜ3回目の反復を待っているのですか?3回目の反復は、約40秒間待機した後、条件が満たされたときです。

私は何が間違っているのですか?

4

3 に答える 3

3

リクエストがタイムアウトした場合は、をキャッチする必要がありますSocketTimeoutExceptionドキュメントを参照)。タイムアウトが発生してもソケットは有効なままであるため、そのキャッチでソケットを閉じます。

于 2012-10-03T13:49:17.983 に答える
1

ここにはいくつか問題がありますが、主な問題は、ソケットを適切に閉じていないことだと思います。これは、独自のブロックではなく、ソケットをカプセル化するブロックのfinallyブロックにある必要があります。trytry

于 2012-10-03T13:50:02.283 に答える
1

SO_TIMEOUTはclose()に影響しません。SO_LINGERを設定してみてください。

于 2012-10-03T18:33:54.560 に答える