【问题标题】:Why this code works only in debug mode with a breakpoint? (IDE Debugger)为什么这段代码只能在带有断点的调试模式下工作? (IDE 调试器)
【发布时间】:2018-02-05 16:32:50
【问题描述】:

你好,我正在用纯 java 编写一个简单的 telnet(稍后我将有一个自定义的 telnet 客户端来解释命令)命令和控制服务器 而且我有一些代码只有在我打开调试器并且断点在正确位置时才有效,这很奇怪

代码:

主要:

package LiteDoor;

import java.io.File;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import LiteDoor.net.AcceptTelnetClient;

public class Main {

    public static final String VERSION = "v0.0.1"; 

    public static File scripts = new File("scripts");

    public static ArrayList<AcceptTelnetClient> conns = new ArrayList<AcceptTelnetClient>();

    public static void main(String args[]) throws Exception
    {
        File autorun = new File(scripts.getAbsolutePath()+File.separatorChar+"autorun.litescript");
        if (!autorun.exists()) {
            scripts.mkdirs();
            autorun.createNewFile();
        }

        ServerSocket Soc=new ServerSocket(666);
        while(true)
        {
            Socket CSoc=Soc.accept();
            AcceptTelnetClient ob=new AcceptTelnetClient(CSoc);
        }
    }

}

接受Telnet客户端:

package LiteDoor.net;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

import LiteDoor.Main;
import LiteDoor.io.MyBufferedWriter;

public class AcceptTelnetClient extends Thread {
    Socket ClientSocket;
    public boolean master;
    public String slaveCmd = null;

    public AcceptTelnetClient(Socket CSoc) throws Exception {
        Main.conns.add(this);

        ClientSocket=CSoc;
        System.out.println("Client Connected ...");
        BufferedReader in  = new BufferedReader(new InputStreamReader(ClientSocket.getInputStream()));
        @SuppressWarnings("resource")
        MyBufferedWriter out = new MyBufferedWriter(new OutputStreamWriter(ClientSocket.getOutputStream()));  

        out.writeln("MASTER/SLAVE?");

        switch(in.readLine().toUpperCase()) {
        case("MASTER"):
            master = true;
            break;
        case("SLAVE"):
            master = false;
            break;
        }

        int i=0;
        while(i<200) {
            out.newLine();
            i++;
        }
        out.flush();

        start();        
    }

    public void run() {
        try {    
            BufferedReader in=new BufferedReader(new InputStreamReader(ClientSocket.getInputStream()));
            @SuppressWarnings("resource")
            MyBufferedWriter out = new MyBufferedWriter(new OutputStreamWriter(ClientSocket.getOutputStream()));  

            out.writeln("");

            if (!master) {
                BufferedReader fr = new BufferedReader(new FileReader(Main.scripts.getAbsolutePath()+File.separatorChar+"autorun.litescript"));
                String line = fr.readLine();
                while(line != null) {
                    if (!line.startsWith("#") && line != "") {
                        out.writeln(line);
                    }
                    line = fr.readLine();
                }
                fr.close();
            }

            boolean loop = true;

            while(loop) {
                if (master) {
                    String cmd = in.readLine();
                    if(cmd.startsWith("quit")) {

                        loop=false;

                    } else {  
                        System.out.println("Master says: " + cmd);
                        for (AcceptTelnetClient con : Main.conns) {
                            if (!con.master) {
                                synchronized (con) {
                                    con.slaveCmd = cmd;
                                }
                            }
                        }
                    }
                } else {
                    if (slaveCmd != null) {
                        synchronized (this) { // Here needs to be an breakpoint
                            out.writeln(slaveCmd);
                            slaveCmd = null;
                        }
                    }
                }
            }
            ClientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                ClientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } 
}

会发生什么:

客户端 1 连接到“从”中的服务器类型 并等待一些命令发送给它

客户端 2 连接“master”中的类型并发送一些命令 然后应该将其发送到作为“从属”连接的所有客户端

会发生什么: 客户端 1 作为从机连接 客户端 2 在主机发送命令时连接,但从机没有得到它(它不会显示在 telnet 客户端窗口中)

代码只能在调试器中正常工作,并且断点在正确的位置

PS 是的,我尝试了谷歌搜索,但一无所获

【问题讨论】:

    标签: java eclipse sockets debugging telnet


    【解决方案1】:

    TL;DR...

    您不能确定正在运行的线程是否获得了布尔标志 master 的更新值,请改为声明 volatile...

     public volatile boolean master;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      • 1970-01-01
      相关资源
      最近更新 更多