4

I am new to socket programming, and have a piece of code which opens a socket and writes into it. I set the timeout for the socket as one minute, and want to close the socket and exit after I reach a certain condition.

My code is not closing the socket when the condition is met:

@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();

Output:

//"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

Why is it waiting on the third iteration? The third iteration is when the condition is met, after waiting for about 40 seconds.

What am I doing wrong?

PermGenError
  • 45,977
  • 8
  • 87
  • 106

3 Answers3

3

You need to catch a SocketTimeoutException (see the doc) if your request times out and then close the socket in that catch, as the socket stays valid even if there is a time out.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
talnicolas
  • 13,885
  • 7
  • 36
  • 56
  • i dont wanna catch the exception. i wanna close the socket once a condition is met in the while(see if cond in the while) even thouh socket timeout is still active – PermGenError Oct 03 '12 at 13:51
  • Have you debugged it, see if it reaches the `socket.close()`? – talnicolas Oct 03 '12 at 13:53
  • yes, it reaches it.. lemme post my output to make it clear – PermGenError Oct 03 '12 at 13:54
  • mmh does the `AFTER WHILE` get printed? Did you try to output something in your last `try`? – talnicolas Oct 03 '12 at 14:12
  • yes it does.. i missed it in the question. everything prints ok .. but as i said on the 3rd iteration it just wait for like 45 secs and then continue the control, 3rd iteration is where the condition is met. and also check the edited question .. – PermGenError Oct 03 '12 at 14:14
  • Well I guess it's probably waiting for something to be written in the stream... What I don't get is if you break out of the while, how come your socket doesn't get closed – talnicolas Oct 03 '12 at 14:25
  • my sockets get close once the loop is breaked, i am only wondering about the wait .. any clue ? – PermGenError Oct 03 '12 at 14:54
  • Well as I already said, I can only guess that it is waiting for something to be written in the stream of the socket... – talnicolas Oct 03 '12 at 15:26
  • @tainicolas i just tested it with a different host and it terminates fine w/o waiting, it was problem with the host i was using, thanks for your answer. – PermGenError Oct 04 '12 at 06:15
1

There are a few problems here, but I think the main one is that you are not closing the socket properly. This should be in the finally block of the try block that encapsulates the sockets, NOT in its own try block.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Jordan Denison
  • 2,649
  • 14
  • 14
1

SO_TIMEOUT does not affect close(), try setting SO_LINGER.

Jan Wrobel
  • 6,969
  • 3
  • 37
  • 53