我是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秒。
我做错了什么?
答案 0 :(得分:3)
如果请求超时,则需要捕获SocketTimeoutException
(请参阅doc)然后关闭该捕获中的套接字,因为即使有超时,套接字仍然有效。< / p>
答案 1 :(得分:1)
这里有一些问题,但我认为主要的一点是你没有正确关闭套接字。这应该在封装套接字的finally
块的try
块中,而不是在它自己的try
块中。
答案 2 :(得分:1)
SO_TIMEOUT does not affect close(),尝试设置SO_LINGER。