设置超时后套接字未关闭

4

我是socket编程的新手,有一段代码可以打开一个socket并向其中写入数据。我设置了socket的超时时间为1分钟,并希望在达到某个条件后关闭socket并退出。

但当满足条件时,我的代码没有关闭socket:

@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

为什么它会在第三次迭代时等待?第三次迭代是当条件满足时,大约等待40秒后。

我做错了什么?


对等方在40秒后发送了OK。套接字在超时时不会自动关闭。这不是一个真正的问题。 - user207421
3个回答

3

如果你的请求超时了,你需要捕获SocketTimeoutException(请参见文档),然后在catch中关闭套接字,因为即使出现超时,套接字仍然有效。


我不想捕获异常。当在while循环中满足条件时,我想关闭套接字,即使套接字的超时仍然生效。 - PermGenError
你调试过它了吗?看看它是否到达了 socket.close() 语句? - talnicolas
是的,它达到了目的。让我发布我的输出以使其清晰明了。 - PermGenError
mmh AFTER WHILE 会被打印吗?你在最后一个 try 中尝试输出了什么吗? - talnicolas
我的套接字一旦循环被打破就会关闭,我只是想知道等待的原因...有什么线索吗? - PermGenError
显示剩余4条评论

1

SO_TIMEOUT 不影响 close(),请尝试设置 SO_LINGER。


1

这里有几个问题,但我认为主要的问题是您没有正确关闭套接字。这应该在封装套接字的try块的finally块中,而不是在自己的try块中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接