我正在尝试使用服务器套接字在客户端和服务器之间建立连接。我也没有使用java.nio
。
问题是我经常发送测试消息,并检测是否成功发送消息(客户端仍然连接),如果没有,则客户端断开连接。
这里显示:
try
{
Scanner in = new Scanner(socket.getInputStream());
BufferedReader in_2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(stopThread)
{
if(in_2.ready())
{
String message = in_2.readLine();
dt = new DateTime();
PrintStream out = new PrintStream(socket.getOutputStream());
server.detect(message, dataSets, out);
dataSets.add(message);
GUI.textArea_1.append(message + "\r\n");
GUI.textArea_1.setCaretPosition(GUI.textArea_1.getDocument().getLength());
}
else
{
PrintStream out = new PrintStream(socket.getOutputStream());
out.println("Testing Connection \r\n");
if(out.checkError())
{
try
{
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
stopThread = false;
GUI.textArea.append(userName + " disconnected \r\n");
GUI.textArea.setCaretPosition(GUI.textArea.getDocument().getLength());
server.inputDataForm(userName, dt, dataSets);
}
Thread.sleep(3000);
}
}
问题是Thread.sleep(3000)
实际上是在干扰获取数据,因为在3秒之后,我将获得大量数据(因为我停止了3秒的线程)。
现在,我建议的是else语句中的匿名类。
class runThread implements runnable
{
void run()
{
//Put the else statement here
}
}
但是stopThread = false不是常数,我正试图控制它。
我搜索过的其他线程只将变量置于匿名类的main中,但如果客户端断开连接,我需要stopThread来停止while循环。
有没有人有想法?
谢谢!
答案 0 :(得分:2)
考虑设置短timeout on your socket.这将允许您控制线程在等待来自套接字的数据时阻塞的时间。
如果数据无法快速获得,则会引发非常具体的java.net.SocketTimeoutException
。您可以通过检查stopThread
标志来处理此异常。如果已设置,则可以从方法返回。否则,套接字仍然有效,您可以尝试使用超时的另一个读取操作。
如果抛出任何其他异常类型,则套接字可能不再有效。
socket.setSoTimeout(20); /* 1/50th of a second. */
BufferedReader in = new BufferedReader
(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
while (!stop) {
try {
String message = in.readLine();
if (message == null)
handleEOF();
else
handleMessage(message);
} catch(SocketTimeoutException ignore) {
/* Loop back to check "stop" flag. */
continue;
} catch(IOException ex) {
handleDisconnection();
break;
}
}
顺便说一下,如果你使用的是Swing,请记住you can only modify graphical components from Swing's Event Dispatch Thread,并且你不能在像这个套接字处理这样的长时间运行中绑定EDT。您应该将任务从此线程传递给Swing的invokeLater()
实用程序。
答案 1 :(得分:1)
为什么不创建一个实现runnable的类,但也有方法stop();
public class MyRunner implements Runnable(){
MutableBoolean stop = false;
public void run(){...}
public void stop(){
stop = true;
}
}