这里我创建一个线程来检查每2秒的服务器响应,问题是client.monitorResponse()
是readLine()
方法,并且在收到响应之前不会继续。
client = new ClientObject("localhost");
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
String response = null;
if(!(response = client.monitorResponse()).isEmpty()) {
System.out.println("Response: " + response);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 2000, 2000);
我通过服务器发送响应,如此(其中client
是已建立的套接字):
public SocketObject(Socket client, int numberOfClients) throws Exception {
socket = client; // the .accept() socket is passed through
// this is because I assign them ID's for later use (I hold an ArrayList of sockets)
this.clientId = numberOfClients;
// both these are static to the class
outputStream = new PrintWriter(client.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(client.getInputStream()));
}
public void sendResponse(String response) {
outputStream.println(response);
}
然后我通过已连接到服务器的客户端Socket选择响应:
public ClientObject(String hostname) throws IOException {
// socket is static to this class
socket = new Socket(hostname, 4444);
System.out.println("Connected to " + hostname + " on port 4444...");
// both static to this class
outputStream = new PrintWriter(socket.getOutputStream(), true);
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Successfully started a stream on " + hostname);
this.hostname = hostname;
}
public String monitorResponse() throws Exception {
System.out.println("Listening for a response...");
return inputStream.readLine();
}
调试控制台只显示侦听响应... 输出,告诉我它没有通过线程内的inputStream.readLine()
方法。无论如何我可以在BufferedReader上添加超时吗?我尝试了多种解决方案,例如在创建BufferedReader之前向套接字添加.setSoTimeout()
,但所有这些都是在指定时间后关闭连接/套接字。
任何帮助都将不胜感激。
答案 0 :(得分:0)
您应该使用非阻塞(NIO)请求并读取块以查找中间的换行符。通常在Java中,您只需要查找正在使用的Stream类的NIO版本,并使用它来检查新内容的每N秒。在您进行最少修改的情况下,您可以使用BufferedReader.ready()
阻止调用的不那么花哨和有效的方法来阻止阻止:
String partialLine="";
public static String monitorResponse() throws Exception {
System.out.println("Listening for a response...");
int nextByte;
String nextChar;
while (inputStream.ready()) {
nextByte = inputStream.read();
nextChar = Character.toString ((char) nextByte);
partialLine += nextChar;
if ("\n".equals(nextChar)) {
String line = partialLine;
partialLine = "";
return line.replace("\r\n", "");
}
}
return "";
}
答案 1 :(得分:0)
无论如何我可以在BufferedReader上添加超时吗?
不,但您可以使用Socket
在Socket.setSoTimeout()
上设置超时。
在创建BufferedReader之前,我尝试过多个解决方案,例如在套接字中添加.setSoTimeout(),但所有这些都是在指定时间后关闭连接/套接字。
不,它没有关闭套接字。它抛出SocketTimeoutException
,你应该抓住并处理相关的内容。如果套接字正在关闭,您将关闭它。解决方案:不要。