我有一个服务器套接字。在TimerTask的帮助下,它每1秒查询服务器并通过输出/输入流读取响应。但是,我收到错误套接字已关闭。
try (
// create TCP socket for the given hostName, remote port PortNumber
Socket echoSocket = new Socket(hostName, portNumber);
// Stream writer to the socket
PrintWriter out =
new PrintWriter(echoSocket.getOutputStream(), true);
// Stream reader from the socket
BufferedReader in =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()))
) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
// Query the server.
out.println("?");
// read response from the socket
String receivedText = in.readLine(); // ** error here
} catch (IOException e) {
e.printStackTrace();
}
}
}, 1000, 1000);
这是服务器套接字:
while (((receivedText = in.readLine()) != null)) {
if (receivedText.equals("?")) {
out.println(getCurrentState());
}
}
// close the connection socket
connectSocket.close();
但是,如果我使用while(true)和Thread.sleep(1000)而不是TimerTask,它可以工作。
答案 0 :(得分:1)
问题在于,将BufferedReader in
放入try
- 资源块后,您的BuferedReader
会在" main"之后立即自动关闭。线程离开try
块的主要部分。这是在调用timer.schedule()
之后发生的。因此,通过调用Timer
启动的timer.schedule()
线程稍后会在触发仅关闭的套接字/文件描述符时看到。
答案 1 :(得分:1)
TimerTask在一个单独的线程中运行,并且如here所述,虽然Socket是线程安全的,但不建议使用多个线程同时读/写Socket连接。
所以,在上面的例子中,Socket和BufferedReader都应该是任务的本地,如下所示:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
try (
// create TCP socket for the given hostName, remote port
// PortNumber
Socket echoSocket = new Socket(hostName, port);
// Stream writer to the socket
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
// Stream reader from the socket
BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));) {
// Query the server.
out.println("?");
// read response from the socket
String receivedText = in.readLine(); // ** error here
} catch (IOException e) {
e.printStackTrace();
}
}
}, 1000, 1000);