0

我正在尝试使用服务器套接字在客户端和服务器之间建立连接。我也不用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 循环。

有人有想法吗?

谢谢!

4

2 回答 2

2

考虑在您的套接字上设置一个短暂的超时。这将允许您控制线程在等待来自套接字的数据时阻塞的时间。

如果数据不能很快得到,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,请记住,您只能从 Swing 的 Event Dispatch Thread 修改图形组件,并且不能将 EDT 捆绑在像这种套接字处理这样的长时间运行的操作中。您应该将此线程中的任务传递给 Swing 的invokeLater()实用程序。

于 2013-05-14T00:30:29.247 回答
1

为什么不创建一个实现可运行但也具有方法 stop() 的类;

public class MyRunner implements Runnable(){
    MutableBoolean stop = false;
    public void run(){...}
    public void stop(){
        stop = true;
    }
}
于 2013-05-13T23:49:16.307 回答