Hello I am writing a simple telnet (later im going to have a custom telnet client which interprets the commands) command and control server in pure java and i have a bit of code that works only when I have debugger on and breakpoint in right place this is weird
Code:
Main:
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);
}
}
}
AcceptTelnetClient:
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();
}
}
}
}
What shloud happen:
Client 1 connects to server types in "slave" and waits till some commands get sended to it
Client 2 connects types in "master" and sends some commands that then shloud get sended to all clients that are connected as "slave"
What happens: Client 1 connects as slave Client 2 connects as master sends a command but slaves dont get it (it does not show in telnet client window)
Code works properly only in debugger and with breakpoint in right place
PS yes i tried googling but found nothing
TL;DR...
you can not be sure that the running thread gets an updated value of the boolean flag master, declare that volatile instead...
public volatile boolean master;