这是生成服务器线程的SocketServer代码
public class ProcessorCorresponder {
protected final static Logger logger = LogManager.getLogger( ProcessorCorresponder.class );
private static int port = Integer.parseInt(PropertiesLoader.getProperty("appserver.port") == null ? "666" : PropertiesLoader.getProperty("appserver.port"));
private static int maxConnections = Integer.parseInt(PropertiesLoader.getProperty("appserver.maxconnections") == null ? "666" : PropertiesLoader.getProperty("appserver.maxconnections"));
public static void main(String[] args) {
logger.info("Starting server .. "
+ "[port->" + port
+ ",databaseName->" + databaseName + "]");
try (ServerSocket listener = new ServerSocket();) {
listener.setReuseAddress(true);
listener.bind(new InetSocketAddress(port));
Socket server;
int i = 0;
while((i++ < maxConnections) || (maxConnections == 0)) {
server = listener.accept();
logger.debug(
"New Thread listening on " + server.getLocalAddress().toString() + ":" + server.getLocalPort()
+ ", initiated from IP => " + server.getInetAddress().toString() + ":" + server.getPort()
);
MySocketServer socSrv = new MySocketServer (server);
Thread t = new Thread( socSrv );
t.start();
}
} catch (Exception ex) {
logger.error("Error in ProcessorInterface", ex);
}
}
}
服务器代码:这是一个处理一个连接的线程,有一个程序监视serversocket并根据需要旋转请求线程。
public class MySocketServer implements Runnable {
protected final static Logger logger = LogManager.getLogger(MySocketServer.class);
private final Socket server;
// because we are using threads, we must make this volatile, or the class will
// never exit.
private volatile boolean shouldContinue = true;
private StringBuffer buffHeartbeatMessage = new StringBuffer().append((char) 0).append((char) 0).append((char) 0)
.append((char) 0).append((char) 0).append((char) 0);
private Heartbeat heartbeat = new Heartbeat(/* 60 */3000, buffHeartbeatMessage.toString());
public MySocketServer(Socket server) {
this.server = server;
}
@Override
public void run() {
try (BufferedReader in = new BufferedReader(new InputStreamReader(this.server.getInputStream()));
BufferedOutputStream out = new HeartbeatBufferedOutputStream(this.server.getOutputStream(),
heartbeat)) {
final StreamListener listener = new StreamListener(in);
listener.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
if (event.getID() == ActionEvent.ACTION_PERFORMED) {
if (event.getActionCommand().equals(StreamListener.ERROR)) {
logger.error("Problem listening to stream.");
listener.setShouldContinue(false);
stopRunning();
} else {
String messageIn = event.getActionCommand();
if (messageIn == null) { // End of Stream;
stopRunning();
} else { // hey, we can do what we were meant for
logger.debug("Request received from client");
// doing stuff here
...
// done doing stuff
logger.debug("Sending Client Response");
try {
sendResponse(opResponse, out);
} catch (Exception ex) {
logger.error("Error sending response to OP.", ex);
}
}
}
}
}
});
listener.start();
while (shouldContinue) {
// loop here until shouldContinue = false;
// this should be set to false in the ActionListener above
}
heartbeat.setShouldStop(true);
return;
} catch (Exception ex) {
logger.error("Error in ESPSocketServer", ex);
return;
}
}
private void stopRunning() {
shouldContinue = false;
}
private void sendResponse(ClientResponse opResponse, BufferedOutputStream out) throws Exception {
logger.debug("Before write");
out.write(opResponse.getResponse().getBytes());
logger.debug("After write. Before flush");
out.flush();
logger.debug("After flush");
// this log message is in my logs, so I know the message was sent
}
}
我的StreamListener类。
public class StreamListener extends Thread {
protected final static Logger logger = LogManager.getLogger(StreamListener.class);
public final static String ERROR = "ERROR";
private BufferedReader reader = null;
private List<ActionListener> actionListeners = new ArrayList<>();
private boolean shouldContinue = true;
public StreamListener(BufferedReader reader) {
this.reader = reader;
}
@Override
public void run() {
while (shouldContinue) {
String message;
try {
// client blocks here and never receives message
message = reader.readLine();
ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, message);
fireActionPerformed(event);
} catch (IOException e) {
e.printStackTrace();
ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ERROR);
fireActionPerformed(event);
}
}
}
public void setShouldContinue(boolean shouldContinue) {
this.shouldContinue = shouldContinue;
}
public boolean getShouldContinue() {
return shouldContinue;
}
public boolean addActionListener(ActionListener listener) {
return actionListeners.add(listener);
}
public boolean removeActionListener(ActionListener listener) {
return actionListeners.remove(listener);
}
private void fireActionPerformed(ActionEvent event) {
for (ActionListener listener : actionListeners) {
listener.actionPerformed(event);
}
}
}
My Heartbeat课程
public class Heartbeat extends Thread {
private BufferedOutputStream bos = null;
private int beatDelayMS = 0;
private String message = null;
private boolean shouldStop = false;
public Heartbeat(int beatDelayMS, String message) {
this.beatDelayMS = beatDelayMS;
this.message = message;
setDaemon(true);
}
@Override
public void run() {
if (bos == null) { return; }
while(!shouldStop) {
try {
sleep(beatDelayMS);
try {
bos.write(message.getBytes());
bos.flush();
} catch (IOException ex) {
// fall thru
}
} catch (InterruptedException ex) {
if (shouldStop) {
return;
}
}
}
}
public void setBufferedOutputStream(BufferedOutputStream bos) {
this.bos = bos;
}
public BufferedOutputStream getBufferedOutputStream() {
return bos;
}
public void setShouldStop(boolean shouldStop) {
this.shouldStop = shouldStop;
}
public boolean getShouldStop() {
return shouldStop;
}
}
My HeartbeatBufferedOutputStream
public class HeartbeatBufferedOutputStream extends BufferedOutputStream {
private Heartbeat heartbeat = null;
public HeartbeatBufferedOutputStream(OutputStream out, Heartbeat heartbeat) {
super(out);
this.heartbeat = heartbeat;
this.heartbeat.setBufferedOutputStream(this);
heartbeat.start();
}
@Override
public synchronized void flush() throws IOException {
super.flush();
heartbeat.interrupt();
}
}
最后这是&#34;客户&#34;类
public class Mockup extends Thread {
protected final static Logger logger = LogManager.getLogger(Mockup.class);
// because we are using threads, we must make this volatile, or the class will
// never exit.
private volatile boolean shouldContinue = true;
public static void main(String[] args) {
new Mockup().start();
}
@Override
public void run() {
try (Socket socket = new Socket("localhost", 16100);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));) {
final StreamListener listener = new StreamListener(in);
listener.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
if (event.getID() == ActionEvent.ACTION_PERFORMED) {
if (event.getActionCommand().equals(StreamListener.ERROR)) {
logger.error("Problem listening to stream.");
listener.setShouldContinue(false);
stopRunning();
} else {
String messageIn = event.getActionCommand();
if (messageIn == null) { // End of Stream;
stopRunning();
} else { // hey, we can do what we were meant for
// convert the messageIn to an OrderPower request, this parses the information
logger.info("Received message from server. [" + messageIn + "].");
}
}
}
}
});
listener.start();
StringBuffer buff = new StringBuffer("Some message to send to server");
logger.info("Sending message to server [" + buff.toString() + "]");
out.write(buff.toString().getBytes());
out.flush();
boolean started = false;
while (shouldContinue) {
if (!started) {
logger.debug("In loop");
started = true;
}
// loop here until shouldContinue = false;
// this should be set to false in the ActionListener above
}
logger.info("Exiting Mockup");
return;
} catch (Exception ex) {
logger.error("Error running MockupRunner", ex);
}
}
private void stopRunning() {
shouldContinue = false;
}
}
我已从日志消息中确认服务器向BufferedOutputStream发送消息并刷新,但客户端日志表明它已在reader.readLine()上被阻止,并且永远不会收到消息。
答案 0 :(得分:1)
你正在读行,但你永远不会写行。在您发送的内容中添加行终止符。