考虑到我的技能水平,我想确保我正确地使用了相关的模式,并遵循了命名约定。这是一个使用Apache 泥浆客户的穷人TelnetClient控制器。项目在GitHub上。
startReadPrintThreads通过实例化工作人员来启动线程,进而启动I/O线程。当接收到消息时,CharacterDataQueueWorker通知控制器,然后控制器将从ConcurrentLinkedQueue<Command>中添加sendMessages,这两个i/o线程都可以将其添加到其中。只有sendCommands才能从commandsQueue中弹出或删除Command。
package telnet;
import static java.lang.System.out;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;
import java.util.Properties;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.commons.net.telnet.TelnetClient;
public final class Controller implements Runnable, Observer {
private TelnetClient telnetClient = new TelnetClient();
private InputStreamWorker remoteOutputWorker = new InputStreamWorker();
private ConsoleReader localInputReader = new ConsoleReader();
private CharacterDataQueueWorker remoteDataQueueWorker = new CharacterDataQueueWorker();
private RemoteOutputRegexMessageWorker remoteMessageWorker = new RemoteOutputRegexMessageWorker();
private final ConcurrentLinkedQueue<Character> remoteCharDataQueue = new ConcurrentLinkedQueue();
private final ConcurrentLinkedQueue<Command> commandsQueue = new ConcurrentLinkedQueue();
private Controller() {
}
public void startReadPrintThreads() throws SocketException, IOException {
remoteOutputWorker.print(telnetClient.getInputStream(), remoteCharDataQueue);
localInputReader.read();
localInputReader.addObserver(this);
remoteDataQueueWorker.read(remoteCharDataQueue);
remoteDataQueueWorker.addObserver(this);
}
private void sendCommands() {
String commandString = null;
Iterator it = commandsQueue.iterator();
byte[] commandBytes = null;
OutputStream outputStream = telnetClient.getOutputStream();
while (it.hasNext()) {
try {
commandBytes = commandsQueue.remove().getCommand().getBytes();
outputStream.write(commandBytes);
outputStream.write(10);
outputStream.flush();
} catch (IOException ex) {
out.println("sendCommand\n" + ex);
}
}
}
@Override
public void update(Observable o, Object arg) {
if (o instanceof CharacterDataQueueWorker) {
String remoteOutputMessage = remoteDataQueueWorker.getFinalData();
remoteMessageWorker.parseWithRegex(remoteOutputMessage);
sendCommands();
}
if (o instanceof ConsoleReader) {
String commandString = localInputReader.getCommand();
Command command = new Command(commandString);
commandsQueue.add(command);
sendCommands();
}
}
@Override
public void run() {
try {
Properties props = PropertiesReader.getProps();
InetAddress host = InetAddress.getByName(props.getProperty("host"));
int port = Integer.parseInt(props.getProperty("port"));
telnetClient.connect(host, port);
startReadPrintThreads();
} catch (UnknownHostException ex) {
out.println(ex);
} catch (SocketException ex) {
out.println(ex);
} catch (IOException ex) {
out.println(ex);
}
}
public static void main(String[] args) throws SocketException, IOException {
new Controller().run();
}
}发布于 2013-09-04 18:44:26
成员变量:您将其中两个变量定义为final,但从不为其中任何一个分配新值。最好把它们都做成final。
sendCommands():
commandString从未被使用过。commandBytes尽可能在最紧的范围内定义它。如果将其定义为try的第一行,则不必担心它是否为null或具有以前用法中的其他值。it.hasNext(),但从未调用it.next()进行迭代,这似乎很奇怪。如果您只关心集合是否有任何剩余值,请使用!commandsQueue.isEmpty()。您要做的是取决于可能更改的实现细节。返回的迭代器可以是集合的快照,如果以后更改集合,则不会更改。update():
我更喜欢有2个Observer实例,而不是必须检查传递给方法的Observable的类型。
https://codereview.stackexchange.com/questions/30784
复制相似问题