package activeMq with tomcat (java) - java

In my application,i have activeMq to send the message from client to server and vice versa.I run it as a standalone server.So when a client machine sends the message,the messages are passed in the activeMq queue and then retrieve by the server(my Application) if and only if the transaction is done locally,meaning the client machine and server(my application) live in the same computer. But when i run the client and server from two different computer meaning server in one and client in another then the client can only establish connection to the server but the messages are not passed to the activeMq queue.I think this is something with activeMq problem.
can anyone tell me how to solve this?
thanks
here is the code which passes the data sent by client to the queue.
package event.activeMq;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.console.command.store.amq.CommandLineSupport;
import org.apache.activemq.util.IndentPrinter;
public class ProducerTool extends Thread {
private Destination destination;
private int messageCount = 1;
private long sleepTime;
private boolean verbose = true;
private int messageSize = 1000;
private static int parallelThreads = 1;
private long timeToLive;
private String user = ActiveMQConnection.DEFAULT_USER;
private String password = ActiveMQConnection.DEFAULT_PASSWORD;
private String url = ActiveMQConnection.DEFAULT_BROKER_URL;
private String subject = "CLOUDD.DEFAULT";
private boolean topic;
private boolean transacted;
private boolean persistent;
private static Object lockResults = new Object();
private static String DateTime="";
private static String TaskID="";
private static String UniqueEventID="";
private static String Generator="";
private static String GeneratorBuildVsn="";
private static String Severity="";
private static String EventText="";
private static String SubsystemID="";
private static String EventNumber="";
private static String atmId="";
public void element(String[] element) {
this.DateTime = element[0];
this.TaskID = element[1];
this.Generator = element[2];
this.Severity = element[3];
this.EventText = element[4];
this.SubsystemID = element[5];
this.EventNumber = element[6];
this.GeneratorBuildVsn = element[7];
this.UniqueEventID = element[8];
this.atmId = element[9];
}
public static void main(String[] args) {
System.out.println("came here");
ArrayList<ProducerTool> threads = new ArrayList();
ProducerTool producerTool = new ProducerTool();
producerTool.element(args);
producerTool.showParameters();
for (int threadCount = 1; threadCount <= parallelThreads; threadCount++) {
producerTool = new ProducerTool();
CommandLineSupport.setOptions(producerTool, args);
producerTool.start();
threads.add(producerTool);
}
while (true) {
Iterator<ProducerTool> itr = threads.iterator();
int running = 0;
while (itr.hasNext()) {
ProducerTool thread = itr.next();
if (thread.isAlive()) {
running++;
}
}
if (running <= 0) {
System.out.println("All threads completed their work");
break;
}
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
}
public void showParameters() {
System.out.println("Connecting to URL: " + url);
System.out.println("Publishing a Message with size " + messageSize + " to " + (topic ? "topic" : "queue") + ": " + subject);
System.out.println("Using " + (persistent ? "persistent" : "non-persistent") + " messages");
System.out.println("Sleeping between publish " + sleepTime + " ms");
System.out.println("Running " + parallelThreads + " parallel threads");
if (timeToLive != 0) {
// System.out.println("Messages time to live " + timeToLive + " ms");
}
}
public void run() {
Connection connection = null;
try {
// Create the connection.
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, password, url);
connection = connectionFactory.createConnection();
connection.start();
// Create the session
Session session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);
if (topic) {
destination = session.createTopic(subject);
} else {
destination = session.createQueue(subject);
}
// Create the producer.
MessageProducer producer = session.createProducer(destination);
if (persistent) {
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
} else {
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
}
if (timeToLive != 0) {
producer.setTimeToLive(timeToLive);
}
// Start sending messages
sendLoop(session, producer);
// System.out.println("[" + this.getName() + "] Done.");
synchronized (lockResults) {
ActiveMQConnection c = (ActiveMQConnection) connection;
// System.out.println("[" + this.getName() + "] Results:\n");
c.getConnectionStats().dump(new IndentPrinter());
}
} catch (Exception e) {
// System.out.println("[" + this.getName() + "] Caught: " + e);
e.printStackTrace();
} finally {
try {
connection.close();
} catch (Throwable ignore) {
}
}
}
protected void sendLoop(Session session, MessageProducer producer) throws Exception {
for (int i = 0; i < messageCount || messageCount == 0; i++) {
TextMessage message = session.createTextMessage(createMessageText(i));
if (verbose) {
String msg = message.getText();
if (msg.length() > 50) {
msg = msg.substring(0, 50) + "...";
}
// System.out.println("[" + this.getName() + "] Sending message: '" + msg + "'");
}
producer.send(message);
if (transacted) {
// System.out.println("[" + this.getName() + "] Committing " + messageCount + " messages");
session.commit();
}
Thread.sleep(sleepTime);
}
}
private String createMessageText(int index) {
StringBuffer buffer = new StringBuffer(messageSize);
buffer.append("DateTime "+DateTime+" EventNumber "+EventNumber+" TaskID "+TaskID+" AtmId "+atmId+
" Generator "+Generator+" GeneratorBuildVsn "+GeneratorBuildVsn+" Severity "+Severity+
" UniqueEventID "+UniqueEventID+" EventText "+EventText+" SubsystemID "+SubsystemID+" End ");
if (buffer.length() > messageSize) {
return buffer.substring(0, messageSize);
}
for (int i = buffer.length(); i < messageSize; i++) {
buffer.append(' ');
}
DateTime="";
EventNumber="";
TaskID="";
atmId="";
Generator="";
GeneratorBuildVsn="";
Severity="";
UniqueEventID="";
EventText="";
SubsystemID="";
return buffer.toString();
}
public void setPersistent(boolean durable) {
this.persistent = durable;
}
public void setMessageCount(int messageCount) {
this.messageCount = messageCount;
}
public void setMessageSize(int messageSize) {
this.messageSize = messageSize;
}
public void setPassword(String pwd) {
this.password = pwd;
}
public void setSleepTime(long sleepTime) {
this.sleepTime = sleepTime;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setTimeToLive(long timeToLive) {
this.timeToLive = timeToLive;
}
public void setParallelThreads(int parallelThreads) {
if (parallelThreads < 1) {
parallelThreads = 1;
}
this.parallelThreads = parallelThreads;
}
public void setTopic(boolean topic) {
this.topic = topic;
}
public void setQueue(boolean queue) {
this.topic = !queue;
}
public void setTransacted(boolean transacted) {
this.transacted = transacted;
}
public void setUrl(String url) {
this.url = url;
}
public void setUser(String user) {
this.user = user;
}
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
}

you need to update your questin with answers on this questions:
What os do you use?
Do you have a firewall like software on pc?
Could you provide here ActiveMQ conf file?
Could you provide a function
which implemented connection establishment?
upd:
I do't understand all your logic but i thk bug here:
try {
Thread.sleep(1000);
} catch (Exception e){
e.printStackTrace();
}
And never never never catch all exceptions! it's very dangerous.
if you want to catch exception, you need to handle it.

Related

Why do I get zero-filled messages from dynamic queue

A requester is sending messages over a normal queue to a responder, indicating a dynamic queue it created as a reply queue. The responder puts these same messages on the reply queue. The responder retrieves all messages correctly.
For each message sent the requester obtains a message from the reply queue, but its body is filled with zeroes. Both programs are written in Java, using com.ibm.mq.allclient-9.2.2.0.jar. When I wrote the same in JavaScript with Node.js and ibmmq for node, everything worked fine.
Requester.java:
package com.hellerim.imq.comm.requester;
import static com.ibm.mq.constants.CMQC.MQENC_INTEGER_NORMAL;
import static com.ibm.mq.constants.CMQC.MQFMT_STRING;
import static com.ibm.mq.constants.CMQC.MQGMO_FAIL_IF_QUIESCING;
import static com.ibm.mq.constants.CMQC.MQGMO_NO_SYNCPOINT;
import static com.ibm.mq.constants.CMQC.MQGMO_NO_WAIT;
import static com.ibm.mq.constants.CMQC.MQGMO_WAIT;
import static com.ibm.mq.constants.CMQC.MQMT_REQUEST;
import static com.ibm.mq.constants.CMQC.MQOO_FAIL_IF_QUIESCING;
import static com.ibm.mq.constants.CMQC.MQOO_INPUT_EXCLUSIVE;
import static com.ibm.mq.constants.CMQC.MQOO_OUTPUT;
import static com.ibm.mq.constants.CMQC.MQPMO_NO_SYNCPOINT;
import static com.ibm.mq.constants.CMQC.MQRC_NO_MSG_AVAILABLE;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import io.netty.util.CharsetUtil;
import net.jcip.annotations.GuardedBy;
public class Requester
{
private static final int WAIT_WHILE_EMPTY = 100; // ms
private static int MAX_MILLIS_BETWEEN_REQUESTS = 100;
private static int LONG_WIDTH_IN_HEX_CHARS = 16;
private static final Charset charset = CharsetUtil.ISO_8859_1;
private MQQueueManager qMgr;
private final MQQueue requestQueue;
private final String queueNamePattern = "TEST.SESSION.*";
private String replyQueueName;
private final MQQueue replyQueue;
private final MQGetMessageOptions getOptions = new MQGetMessageOptions();
private static final String MQ_MANAGER = "MY_QM";
private static final String REQUEST_QUEUE = "TEST.REQUESTS";
private static final String MODEL_QUEUE = "TEST.SESSION.MODEL";
final private Object locker = new Object();
#GuardedBy("this")
boolean stopped = false;
int rcvd = 0;
public static void main(String[] args) {
try {
Requester rq = new Requester(MQ_MANAGER, REQUEST_QUEUE, MODEL_QUEUE);
List<String> poem = writePoem();
Random requestIds = new Random();
Random delays = new Random(1000);
int cnt = 0;
int position = 0;
for (int i = 0; i < 50; ++i) {
if (i == poem.size()) {
int requestId = requestIds.nextInt(99999) + 1;
String text = poem.stream().collect(Collectors.joining("\n"));
String request = appRequestFrom(text, requestId);
rq.write(request);
System.out.println("Requester: sent request no " + (++cnt) + " - " + requestId);
}
position %= poem.size();
String line = poem.get(position);
int requestId = requestIds.nextInt(99999) + 1;
String request = appRequestFrom(line, requestId);
rq.write(request);
System.out.println("Requester: sent request no " + (++cnt) + " - " + requestId);
position++;
try {
Thread.sleep((long) Math.ceil((Math.pow(
delays.nextDouble(), 4) * MAX_MILLIS_BETWEEN_REQUESTS) + 1));
} catch (InterruptedException e) {
// ignore
}
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// ignore
}
rq.close();
} catch (MQException e) {
e.printStackTrace();
}
}
public Requester(String mqManagerName, String requestQueueName, String modelQueueName) throws MQException {
super();
System.out.println("Requester: establishing mq session (mq manager: " + mqManagerName +
"/ request queue: " + requestQueueName + " / model queue: " + modelQueueName +")");
qMgr = new MQQueueManager(mqManagerName);
// get request queue
int openOptions = MQOO_OUTPUT + MQOO_FAIL_IF_QUIESCING;
requestQueue = qMgr.accessQueue(requestQueueName, openOptions);
// get dynamic reply queue
int inputOptions = MQOO_INPUT_EXCLUSIVE + MQOO_FAIL_IF_QUIESCING;
replyQueue = new MQQueue(qMgr,
modelQueueName,
inputOptions,
"",
queueNamePattern,
"");
replyQueueName = replyQueue.getName();
System.out.println("Requester: created temporary reply queue " + replyQueueName);
getOptions.options = MQGMO_NO_SYNCPOINT +
MQGMO_NO_WAIT +
MQGMO_FAIL_IF_QUIESCING;
// catch-up (for those replies not retrieved after a request was put)
Executors.newSingleThreadExecutor().execute(new Runnable() {
#Override
public void run() {
// read options
MQGetMessageOptions getOptions = new MQGetMessageOptions();
getOptions.options = MQGMO_NO_SYNCPOINT +
MQGMO_WAIT +
MQGMO_FAIL_IF_QUIESCING;
getOptions.waitInterval = WAIT_WHILE_EMPTY;
while(proceed()) {
try {
if (!retrieveMessage(getOptions)) {
try {
Thread.sleep(getOptions.waitInterval);
} catch (InterruptedException e1) {}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
private boolean retrieveMessage(MQGetMessageOptions getOptions) throws IOException {
MQMessage msg = new MQMessage();
try {
msg.clearMessage();
msg.seek(0);
replyQueue.get(msg, getOptions);
System.out.println("Requester: reply no " + ++rcvd + " received - id: " +
Long.parseLong(new String(msg.messageId, Charset.forName("ISO_8859_1")), 16));
byte[] buf = new byte[msg.getDataLength()];
String message = new String(buf, charset);
System.out.println("Requester: message received:\n" + message);
} catch (MQException e) {
if (e.reasonCode == MQRC_NO_MSG_AVAILABLE) {
return false;
}
}
return true;
}
public byte[] write(String message) {
int positionRequestId = 24;
int endIndex = positionRequestId + 16;
CharSequence requestId = message.substring(positionRequestId, endIndex);
StringBuffer sb = new StringBuffer("00000000");
sb.append(requestId);
byte[] id = sb.toString().getBytes(charset);
MQMessage mqMsg = new MQMessage();
mqMsg.characterSet = 819;
mqMsg.encoding = MQENC_INTEGER_NORMAL;
mqMsg.format = MQFMT_STRING;
mqMsg.messageType = MQMT_REQUEST;
mqMsg.messageId = id;
mqMsg.correlationId = id;
mqMsg.replyToQueueName = replyQueueName;
try {
mqMsg.writeString(message);
mqMsg.seek(0);
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.options = MQPMO_NO_SYNCPOINT;
requestQueue.put(mqMsg, pmo);
} catch (IOException e) {
e.printStackTrace();
} catch (MQException e) {
e.printStackTrace();
}
// try to read from reply queue fail immediately
try {
retrieveMessage(getOptions);
} catch (IOException e) {
e.printStackTrace();
}
return id;
}
public void close() {
stop();
try {
Thread.sleep(2 * WAIT_WHILE_EMPTY);
} catch (InterruptedException e1) {
// ignore
}
try {
if (requestQueue != null) {
requestQueue.close();
}
if (qMgr != null) {
qMgr.disconnect();
}
} catch (MQException e) {
// ignore
}
}
public boolean proceed() {
synchronized(locker) {
return !stopped;
}
}
public void stop() {
synchronized(locker) {
stopped = true;
}
}
private static List<String> writePoem() {
List<String> poem = new ArrayList<>();
poem.add("Das Nasobem");
poem.add("von Joachim Ringelnatz");
poem.add("");
poem.add("Auf seiner Nase schreitet");
poem.add("einher das Nasobem,");
poem.add("von seineme Kind begleitet -");
poem.add("es steht noch nicht im Brehm.");
poem.add("");
poem.add("Es steht noch nicht im Meyer");
poem.add("und auch im Brockhaus nicht -");
poem.add("es tritt aus meiner Leier");
poem.add("zum ersten Mal ans Licht.");
poem.add("");
poem.add("Auf seiner Nase schreitet");
poem.add("- wie schon gesagt - seitdem");
poem.add("von seinem Kind begleitet");
poem.add("einher das Nasobem.");
poem.add("");
poem.add("");
return poem;
}
private static String iToHex(int num, int places) {
StringBuilder sb = new StringBuilder();
char[] digits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
for (int i = 0; i < places; ++i) {
sb.append(digits[num % places]);
num /= places;
}
return sb.reverse().toString();
}
private static String iToHex(int num) {
return iToHex(num, LONG_WIDTH_IN_HEX_CHARS);
}
private static String appRequestFrom(String msgBody, int requestId) {
int headerLength = 72;
// includes message body length field here!
int bodyLength = msgBody.length();
StringBuilder sb = new StringBuilder();
sb.append("GHI "); // magic
sb.append("1"); // version major
sb.append("0"); // version minor
sb.append("0"); // flags
sb.append("1"); // app message type SYNCHRONOUS REQUEST
sb.append(iToHex(headerLength + bodyLength)); // message length
sb.append(iToHex(requestId)); // request id
sb.append(iToHex(0)); // timeout
sb.append(iToHex(bodyLength)); // message body length
sb.append(msgBody); // message body
return sb.toString();
}
}
Responder.java:
package com.hellerim.imq.comm.responder;
import static com.ibm.mq.constants.CMQC.*;
import java.io.EOFException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import io.netty.util.CharsetUtil;
import net.jcip.annotations.GuardedBy;
public class Responder
{
private MQQueueManager qMgr;
private MQQueue requestQueue;
private Map<String, MQQueue> replyQueues = new HashMap<>();
private final Object locker = new Object();
static final private int WAIT_WHILE_EMPTY = 100; // ms
#GuardedBy("locker")
private boolean stopped = false;
Thread fetcherThread = null;
private final static byte MESSAGE_TYPE_REPLY = 52; // '4'
public final static String MQ_MANAGER = "MY_QM";
public final static String REQUEST_QUEUE = "TEST.REQUESTS";
public static void main( String[] args ) throws MQException, IOException
{
System.out.println( "running reponder application" );
try {
new Responder(MQ_MANAGER, REQUEST_QUEUE).start();
} catch(Exception e) {
e.printStackTrace();
}
}
public Responder(String mqManagerName, String requestQueueName) throws MQException {
System.out.println("establishing mq session (mq manager: " + mqManagerName +
" / request queue: " + requestQueueName + ")");
qMgr = new MQQueueManager(mqManagerName);
int openOptions = MQOO_INPUT_SHARED + MQOO_FAIL_IF_QUIESCING;
requestQueue = qMgr.accessQueue(requestQueueName, openOptions);
}
public MQQueue getReplyQueue(String replyQueueName) throws MQException {
if (replyQueues.containsKey(replyQueueName)) {
return replyQueues.get(replyQueueName);
}
int openOptions = MQOO_OUTPUT + MQOO_FAIL_IF_QUIESCING;
MQQueue replyQueue = qMgr.accessQueue(replyQueueName, openOptions);
replyQueues.put(replyQueueName, replyQueue);
System.out.println("Responder: opened dynamic reply queue");
return replyQueue;
}
private void start() throws IOException {
Runnable fetcher = new Runnable() {
#Override
public void run() {
int cnt = 0;
while(proceed()) {
MQMessage msg = new MQMessage();
try {
//msg.clearMessage();
MQGetMessageOptions getOptions = new MQGetMessageOptions();
getOptions.options = MQGMO_NO_SYNCPOINT +
MQGMO_WAIT +
MQGMO_FAIL_IF_QUIESCING;
getOptions.waitInterval = WAIT_WHILE_EMPTY;
requestQueue.get(msg, getOptions);
System.out.println("Responder: message no " + ++cnt + " received");
MQQueue replyQueue = null;
try {
replyQueue = getReplyQueue(msg.replyToQueueName);
} catch(MQException e) {
if (e.completionCode == MQCC_FAILED && e.reasonCode == MQRC_UNKNOWN_OBJECT_NAME) {
// dynamic reply queue does not exist any more => message out of date
continue;
}
throw e;
}
// set message type for reply
if (msg.getDataLength() < 56) {
System.out.println("invalid message:");
System.out.println(Msg2Text(msg));
continue;
}
System.out.println(Msg2Text(msg));
int typePosition = 7;
msg.seek(typePosition);
msg.writeByte(MESSAGE_TYPE_REPLY);
msg.seek(0);
String text = Msg2Text(msg);
MQMessage msgOut = new MQMessage();
msgOut.characterSet = 819;
msgOut.encoding = MQENC_INTEGER_NORMAL;
msgOut.format = MQFMT_STRING;
msgOut.messageType = MQMT_REPLY;
msgOut.messageId = msg.messageId;
msgOut.correlationId = msg.correlationId;
msgOut.seek(0);
msgOut.writeString(text);
msgOut.seek(0);
System.out.println(text);
// System.out.println("Responder: message received");
MQPutMessageOptions pmo = new MQPutMessageOptions(); // accept the defaults, same
pmo.options = MQPMO_NO_SYNCPOINT;
replyQueue.put(msgOut, pmo);
System.out.println("Responder: message no " + cnt + " returned");
} catch (MQException e) {
if (e.reasonCode == MQRC_NO_MSG_AVAILABLE) {
; // NOOP
} else {
try {
msg.seek(0);
System.out.println(msg);
} catch (EOFException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
e.printStackTrace();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {}
}
} catch (IOException e) {
e.printStackTrace();
}
}
shutdown();
}
};
Thread task = new Thread(fetcher);
task.run();
System.out.print("press <ENTER> to terminate ");
System.in.read();
System.out.println();
synchronized(locker) {
stopped = true;
}
try {
task.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static String Msg2Text(MQMessage msg) {
int length;
String text = "";
try {
length = msg.getDataLength();
byte[] buf = new byte[length];
msg.seek(0);
msg.readFully(buf);
text = new String(buf, CharsetUtil.ISO_8859_1);
msg.seek(0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return text;
}
private boolean proceed() {
synchronized(locker) {
return !stopped;
}
}
private void shutdown() {
System.out.print("\nshutting down responder... ");
for (MQQueue queue : replyQueues.values()) {
try {
queue.close();
} catch (MQException e) { }
}
replyQueues.clear();
try {
qMgr.close();
} catch (MQException e) { }
System.out.println("done.");
}
}
Is there any idea what might be wrong?
It looks like you have created a buffer the right size for the message data and printed that, without moving the data into it.
In retrieveMessage:
byte[] buf = new byte[msg.getDataLength()];
String message = new String(buf, charset);
System.out.println("Requester: message received:\n" + message);
You might need to call the readFully (or similar) method to get the data.
If you know that your message payload is text (string) then you can do this:
String msgStr = msg.readStringOfByteLength(msg.getMessageLength());
System.out.println("Requester: message received:\n" + msgStr);

UDP Socket: java.net.SocketException: socket closed

MessageCreator: Encapsulate and resolve ports and device unique identifiers.
public class MessageCreator {
private static final String HEADER_PORT = "to port:";
private static final String HEADER_SN = "My sn:";
public static String buildWithPort(int port) {
return HEADER_PORT + port;
}
public static int parsePort(String data) {
if (data.startsWith(HEADER_PORT)) {
return Integer.parseInt(data.substring(HEADER_PORT.length()));
}
return -1;
}
public static String buildWithSn(String sn) {
return HEADER_SN + sn;
}
public static String parseSn(String data) {
if (data.startsWith(HEADER_SN)) {
return data.substring(HEADER_SN.length());
}
return null;
}
}
UdpProvider: Loop to listen to a specific port, then parse the received data, determine whether the data conforms to the predetermined format, get the sender's response port from it, and respond with the uniquely identified UUID value to the UDP searcher.
public class UdpProvider {
public static void main(String[] args) throws IOException {
String sn = UUID.randomUUID().toString();
Provider provider = new Provider(sn);
provider.start();
// Warning: Result of 'InputStream.read()' is ignored
System.in.read();
provider.exit();
}
private static class Provider extends Thread {
private DatagramSocket ds = null;
private boolean done = false;
private final String sn;
public Provider(String sn) {
super();
this.sn = sn;
}
#Override
public void run() {
super.run();
try {
ds = new DatagramSocket(20000);
while (!done) {
final byte[] buf = new byte[512];
DatagramPacket receivePak = new DatagramPacket(buf, buf.length);
ds.receive(receivePak);
String ip = receivePak.getAddress().getHostAddress();
int port = receivePak.getPort();
byte[] receivePakData = receivePak.getData();
String receiveData = new String(receivePakData, 0, /*receivePakData.length*/receivePak.getLength());
System.out.println("received from -> ip: " + ip + ", port: " + port + ", data: " + receiveData);
int responsePort = MessageCreator.parsePort(receiveData.trim());
if (responsePort != -1) {
String responseData = MessageCreator.buildWithSn(sn);
byte[] bytes = responseData.getBytes(StandardCharsets.UTF_8);
DatagramPacket responsePak = new DatagramPacket(bytes, bytes.length,
/*InetAddress.getLocalHost()*/
receivePak.getAddress(),
responsePort);
ds.send(responsePak);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close();
}
}
public void exit() {
done = true;
close();
}
public void close() {
if (ds != null) {
ds.close();
ds = null;
}
}
}
}
UdpSearcher: Listening to a specific port and sending a LAN broadcast, sending a broadcast sets the listening port in the data, so you need to turn on listening first to finish before you can send a broadcast, and once you receive the response data, you can parse the device information
public class UdpSearcher {
private static final int LISTENER_PORT = 30000;
public static void main(String[] args) throws IOException, InterruptedException {
Listener listener = listen();
sendBroadcast();
// Warning: Result of 'InputStream.read()' is ignored
System.in.read();
List<Device> deviceList = listener.getDevicesAndClose();
for (Device device : deviceList) {
System.out.println(device);
}
}
public static void sendBroadcast() throws IOException {
DatagramSocket ds = new DatagramSocket();
String sendData = MessageCreator.buildWithPort(LISTENER_PORT);
byte[] sendDataBytes = sendData.getBytes(StandardCharsets.UTF_8);
DatagramPacket sendPak = new DatagramPacket(sendDataBytes, sendDataBytes.length);
sendPak.setAddress(InetAddress.getByName("255.255.255.255"));
sendPak.setPort(20000);
ds.send(sendPak);
ds.close();
}
public static Listener listen() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
Listener listener = new Listener(LISTENER_PORT, countDownLatch);
listener.start();
countDownLatch.await();
return listener;
}
private static class Listener extends Thread {
private final int listenPort;
private DatagramSocket ds = null;
private boolean done = false;
private final CountDownLatch countDownLatch;
private List<Device> devices = new ArrayList<>();
public Listener(int listenPort, CountDownLatch countDownLatch) {
super();
this.listenPort = listenPort;
this.countDownLatch = countDownLatch;
}
#Override
public void run() {
super.run();
countDownLatch.countDown();
try {
ds = new DatagramSocket(listenPort);
while (!done) {
final byte[] buf = new byte[512];
DatagramPacket receivePak = new DatagramPacket(buf, buf.length);
ds.receive(receivePak);
String ip = receivePak.getAddress().getHostAddress();
int port = receivePak.getPort();
byte[] data = receivePak.getData();
String receiveData = new String(data, 0, /*data.length*/receivePak.getLength());
String sn = MessageCreator.parseSn(receiveData);
System.out.println("received from -> ip: " + ip + ", port: " + port + ", data: " + receiveData);
if (sn != null) {
Device device = new Device(ip, port, sn);
devices.add(device);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close();
}
}
public void close() {
if (ds != null) {
ds.close();
ds = null;
}
}
public List<Device> getDevicesAndClose() {
done = true;
close();
return devices;
}
}
private static class Device {
private String ip;
private int port;
private String sn;
public Device(String ip, int port, String sn) {
this.ip = ip;
this.port = port;
this.sn = sn;
}
#Override
public String toString() {
return "Device{" +
"ip='" + ip + '\'' +
", port=" + port +
", sn='" + sn + '\'' +
'}';
}
}
}
UdpProvider and UdpSearcher worked fine and printed corrresponding data until I input a char sequence from keyboard follwed by pressing Enter key on each console window, both threw an exception on this line ds.receive(receivePak); :

failed to open stream: HTTP request failed using phpjavabridge

i have problem when i use php java bridge i got error like this
Warning: require_once(http://localhost:8080/JavaBridge/java/Java.inc): failed to open stream: HTTP request failed! in /Library/WebServer/Documents/test2.php on line 3
Fatal error: require_once(): Failed opening required 'http://localhost:8080/JavaBridge/java/Java.inc' (include_path='.:') in /Library/WebServer/Documents/test2.php on line 3
my tomcat has running at port 8080. i use force to use port 8080 but i still got error
here my standalone class for java bridge
package php.java.bridge;
import php.java.bridge.util.Thread;
import java.lang.reflect.Method;
import php.java.bridge.http.JavaBridgeRunner;
import php.java.bridge.util.Logger;
import java.io.File;
import javax.swing.Icon;
import java.awt.Component;
import javax.swing.JOptionPane;
import java.net.ServerSocket;
import java.io.IOException;
import php.java.bridge.http.TCPServerSocket;
import php.java.bridge.http.ISocketFactory;
public class Standalone
{
public static final int HTTP_PORT_BASE = 8080;
public static final int HTTPS_PORT_BASE = 8443;
public static ISocketFactory bind(final int logLevel, final String sockname) throws IOException {
ISocketFactory socket = null;
socket = TCPServerSocket.create(sockname, 20);
if (null == socket) {
throw new IOException("Could not create socket: " + sockname);
}
return socket;
}
protected static void disclaimer() {
System.err.println("Copyright (C) 2003, 2006 Jost Boekemeier and others.");
System.err.println("This is free software; see the source for copying conditions. There is NO");
System.err.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
}
protected void javaUsage() {
System.err.println("PHP/Java Bridge version " + Util.VERSION);
disclaimer();
System.err.println("Usage: java -jar JavaBridge.jar [SOCKETNAME LOGLEVEL LOGFILE]");
System.err.println("SOCKETNAME is one of INET_LOCAL, INET, HTTP_LOCAL, HTTP, HTTPS_LOCAL, HTTPS");
System.err.println("");
System.err.println("Example 1: java -jar JavaBridge.jar");
System.err.println("Example 2: java -jar JavaBridge.jar HTTP_LOCAL:8080 3 JavaBridge.log");
System.err.println("Example 3: java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=YOURPASSWD -jar JavaBridge.jar HTTPS:8443 3 JavaBridge.log");
System.err.println("The certificate for example 3 can be created with e.g.: jdk1.6.0/bin/keytool -keystore mySrvKeystore -genkey -keyalg RSA");
System.err.println("");
System.err.println("Influential system properties: threads, daemon, php_exec, default_log_file, default_log_level, base.");
System.err.println("Example: java -Djava.awt.headless=\"true\" -Dphp.java.bridge.threads=50 -Dphp.java.bridge.base=/usr/lib/php/modules -Dphp.java.bridge.php_exec=/usr/local/bin/php-cgi -Dphp.java.bridge.default_log_file= -Dphp.java.bridge.default_log_level=5 -jar JavaBridge.jar");
System.err.println("Example: java -Dphp.java.bridge.daemon=\"true\" -jar JavaBridge.jar");
}
protected void usage() {
this.javaUsage();
System.exit(1);
}
protected void checkOption(final String[] s) {
if ("--version".equals(s[0])) {
System.out.println(Util.VERSION);
System.exit(0);
}
this.usage();
}
private static boolean testPort(final int port) {
try {
final ServerSocket sock = new ServerSocket(port);
sock.close();
return true;
}
catch (IOException ex) {
return false;
}
}
private static int findFreePort(final int start) {
for (int port = start; port < start + 100; ++port) {
if (testPort(port)) {
return port;
}
}
return start;
}
public void init(final String[] s) {
String sockname = null;
int logLevel = -1;
// final String tcpSocketName = "9267";
final String tcpSocketName = "8080";
if (s.length > 3) {
this.checkOption(s);
}
try {
if (s.length > 0) {
sockname = s[0];
if (sockname.startsWith("-")) {
this.checkOption(s);
}
}
try {
if (s.length > 1) {
logLevel = Integer.parseInt(s[1]);
}
}
catch (NumberFormatException e2) {
this.usage();
}
catch (Throwable t) {
t.printStackTrace();
}
if (s.length == 0) {
try {
/* final int tcpSocket = Integer.parseInt(tcpSocketName);
final int freeJavaPort = findFreePort(tcpSocket);
final int freeHttpPort = findFreePort(8080);
final int freeHttpsPort = findFreePort(8443);
final Object result = JOptionPane.showInputDialog(null, "Start a socket listener on port", "Starting the PHP/Java Bridge ...", 3, null, new String[] { "INET_LOCAL:" + freeJavaPort, "INET:" + freeJavaPort, "HTTP_LOCAL:" + freeHttpPort, "HTTP:" + freeHttpPort, "HTTPS_LOCAL:" + freeHttpsPort, "HTTPS:" + freeHttpsPort }, "HTTP_LOCAL:" + freeHttpPort);
//final Object result = 8080;
if (result == null) {
System.exit(0);
}*/
//sockname = result.toString();
sockname = "8080";
}
catch (Throwable t2) {}
}
if (s.length == 0) {
TCPServerSocket.TCP_PORT_BASE = Integer.parseInt(tcpSocketName);
}
if (checkServlet(logLevel, sockname, s)) {
return;
}
final ISocketFactory socket = bind(logLevel, sockname);
if ("true".equals(System.getProperty("php.java.bridge.test.startup"))) {
System.exit(0);
}
JavaBridge.initLog(String.valueOf(socket), logLevel, s);
JavaBridge.init(socket, logLevel, s);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
public static File getCanonicalWindowsFile(final String path) {
try {
return new File(path).getCanonicalFile();
}
catch (IOException e) {
return new File(path);
}
}
private static boolean checkServlet(final int logLevel, String sockname, final String[] s) throws InterruptedException, IOException {
if (sockname == null) {
return false;
}
if (sockname.startsWith("SERVLET_LOCAL:") || sockname.startsWith("HTTP_LOCAL:") || sockname.startsWith("HTTPS_LOCAL:")) {
Util.JAVABRIDGE_PROMISCUOUS = false;
System.setProperty("php.java.bridge.promiscuous", "false");
}
else {
if (!sockname.startsWith("SERVLET:") && !sockname.startsWith("HTTP:") && !sockname.startsWith("HTTPS:")) {
return false;
}
Util.JAVABRIDGE_PROMISCUOUS = true;
System.setProperty("php.java.bridge.promiscuous", "true");
}
final boolean isSecure = sockname.startsWith("HTTPS");
JavaBridge.initLog(sockname, logLevel, s);
sockname = sockname.substring(sockname.indexOf(58) + 1);
final String serverPort = (Util.JAVABRIDGE_PROMISCUOUS ? "INET:" : "INET_LOCAL:") + sockname;
Logger.logMessage("JavaBridgeRunner started on port " + serverPort);
Class runner = JavaBridgeRunner.class;
JavaBridgeRunner r;
try {
runner = Util.classForName("php.java.script.JavaBridgeScriptRunner");
final Method m = runner.getMethod("getRequiredInstance", String.class, Boolean.TYPE);
r = (JavaBridgeRunner)m.invoke(runner, serverPort, new Boolean(isSecure));
}
catch (Throwable e) {
r = JavaBridgeRunner.getRequiredInstance(serverPort, isSecure);
}
r.waitFor();
r.destroy();
return true;
}
private static final boolean checkGNUVM() {
try {
return "libgcj".equals(System.getProperty("gnu.classpath.vm.shortname"));
}
catch (Throwable t) {
return false;
}
}
public static void main(final String[] s) {
if (!System.getProperty("php.java.bridge.daemon", "false").equals("false")) {
final String[] args = new String[s.length + 8];
args[0] = System.getProperty("php.java.bridge.daemon");
if ("true".equals(args[0])) {
args[0] = "java";
}
args[1] = "-Djava.library.path=" + System.getProperty("java.library.path", ".");
args[2] = "-Djava.ext.dirs=" + System.getProperty("java.ext.dirs", ".");
args[3] = "-Djava.awt.headless=" + System.getProperty("java.awt.headless", "true");
args[4] = "-Dphp.java.bridge.asDaemon=true";
args[5] = "-classpath";
args[6] = System.getProperty("java.class.path", ".");
args[7] = "php.java.bridge.Standalone";
for (int j = 0; j < s.length; ++j) {
args[j + 8] = s[j];
}
try {
System.in.close();
System.out.close();
System.err.close();
}
catch (IOException e) {
System.exit(12);
}
new Thread(new Runnable() {
#Override
public void run() {
try {
Runtime.getRuntime().exec(args);
}
catch (IOException e) {
System.exit(13);
}
}
}).start();
try {
java.lang.Thread.sleep(20000L);
}
catch (Throwable t2) {}
System.exit(0);
}
try {
System.loadLibrary("natcJavaBridge");
}
catch (Throwable t3) {}
try {
final String cp = System.getProperty("java.class.path", ".");
File jbFile = null;
final boolean isExecutableJavaBridgeJar = cp.indexOf(File.pathSeparatorChar) == -1 && cp.endsWith("JavaBridge.jar") && (jbFile = new File(cp)).isAbsolute();
final File wd = getCanonicalWindowsFile(isExecutableJavaBridgeJar ? jbFile.getParent() : "");
final boolean sunJavaInstalled = new File("/usr/java/default/bin/java").exists();
final String javaExec = sunJavaInstalled ? "/usr/java/default/bin/java" : "java";
if (s.length == 0 && System.getProperty("php.java.bridge.exec_sun_vm", "true").equals("true") && ((sunJavaInstalled && checkGNUVM()) || isExecutableJavaBridgeJar)) {
final Process p = Runtime.getRuntime().exec(new String[] { javaExec, "-Dphp.java.bridge.exec_sun_vm=false", "-classpath", cp, "php.java.bridge.Standalone" }, null, wd);
if (p != null) {
System.exit(p.waitFor());
}
}
}
catch (Throwable t4) {}
try {
new Standalone().init(s);
}
catch (Throwable t) {
t.printStackTrace();
System.exit(9);
}
}
}
in this source code i force manual choice 8080 using this code
/* final int tcpSocket = Integer.parseInt(tcpSocketName);
final int freeJavaPort = findFreePort(tcpSocket);
final int freeHttpPort = findFreePort(8080);
final int freeHttpsPort = findFreePort(8443);
final Object result = JOptionPane.showInputDialog(null, "Start a socket listener on port", "Starting the PHP/Java Bridge ...", 3, null, new String[] { "INET_LOCAL:" + freeJavaPort, "INET:" + freeJavaPort, "HTTP_LOCAL:" + freeHttpPort, "HTTP:" + freeHttpPort, "HTTPS_LOCAL:" + freeHttpsPort, "HTTPS:" + freeHttpsPort }, "HTTP_LOCAL:" + freeHttpPort);
//final Object result = 8080;
if (result == null) {
System.exit(0);
}*/
//sockname = result.toString();
sockname = "8080";
}
and at tcpServer i force to choice that port use this code
import java.net.Socket;
import java.net.UnknownHostException;
import java.net.InetAddress;
import java.io.IOException;
import java.net.ServerSocket;
public class TCPServerSocket implements ISocketFactory
{
public static int TCP_PORT_BASE;
private ServerSocket sock;
private int port;
boolean local;
public static ISocketFactory create(String name, final int backlog) throws IOException {
boolean local = false;
if (name == null) {
throw new NullPointerException("name");
}
if (name.startsWith("INET:")) {
name = name.substring(5);
}
else if (name.startsWith("INET_LOCAL:")) {
local = true;
name = name.substring(11);
}
final int p = Integer.parseInt(name);
final TCPServerSocket s = new TCPServerSocket(p, backlog, local);
return s;
}
private ServerSocket newServerSocket(final int port, final int backlog) throws IOException {
try {
if (this.local) {
return new ServerSocket(port, backlog, InetAddress.getByName("127.0.0.1"));
}
}
catch (UnknownHostException ex) {}
return new ServerSocket(port, backlog);
}
private void findFreePort(final int start, final int backlog) {
int port = start;
while (port < start + 100) {
try {
this.sock = this.newServerSocket(port, backlog);
this.port = port;
return;
}
catch (IOException e) {
++port;
continue;
}
}
}
private TCPServerSocket(final int port, final int backlog, final boolean local) throws IOException {
this.local = local;
if (port == 0) {
this.findFreePort(TCPServerSocket.TCP_PORT_BASE, backlog);
}
else {
this.sock = this.newServerSocket(port, backlog);
this.port = port;
}
}
#Override
public void close() throws IOException {
this.sock.close();
}
#Override
public Socket accept() throws IOException {
final Socket s = this.sock.accept();
s.setTcpNoDelay(true);
return s;
}
#Override
public String getSocketName() {
return String.valueOf(this.port);
}
#Override
public String toString() {
return (this.local ? "INET_LOCAL:" : "INET:") + this.getSocketName();
}
static {
// TCPServerSocket.TCP_PORT_BASE = 9267;
TCPServerSocket.TCP_PORT_BASE = 8080;
}
}
but my javabridge cannot open stream at that port why like that ? any idea for choice only port 8080 not choice the other ?
this problem close after i change this code
try { /*
final int tcpSocket = Integer.parseInt(tcpSocketName);
final int freeJavaPort = findFreePort(tcpSocket);
final int freeHttpPort = findFreePort(8080);
final int freeHttpsPort = findFreePort(8443);
final Object result = JOptionPane.showInputDialog(null, "Start a socket listener on port", "Starting the PHP/Java Bridge ...", 3, null, new String[] { "INET_LOCAL:" + freeJavaPort, "INET:" + freeJavaPort, "HTTP_LOCAL:" + freeHttpPort, "HTTP:" + freeHttpPort, "HTTPS_LOCAL:" + freeHttpsPort, "HTTPS:" + freeHttpsPort }, "HTTP_LOCAL:" + freeHttpPort);
//final Object result = 8080;
if (result == null) {
System.exit(0);
}*/
//sockname = result.toString();
sockname = "HTTP_LOCAL:8080";
System.out.println("sockname"+sockname);
}
so sockname use "HTTP_LOCAL:8080" not "8080"

Have problem with understanding threads and changing variable in multiple threads

I am trying to restrict the amount of clients on my server,so i just sending message from my server when it is full and print it in my client by ending process for him.But as i use multiple threads i cant stop my writeMessage thread
Tried AtomicBoolean,but i didnt work
public class Client {
private static final Logger LOGGER = LogManager.getLogger();
private BufferedReader consoleReader;
private String name;
private String address;
private int port;
private Thread writeMessage, readMessage;
private ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC"));
private LocalTime dTime = zonedDateTime.toLocalTime();
private Net net;
private AtomicBoolean running = new AtomicBoolean(true);
public Client(String address, int port) {
this.address = address;
this.port = port;
net = new Net(address, port);
consoleReader = new BufferedReader(new InputStreamReader(System.in));
printName();
readMessage();
writeMessage();
}
private void printName() {
System.out.println("Print your name:");
try {
name = consoleReader.readLine();
while (NameValidator.nameIsValid(name)) {
System.out.println("Name should contain more than 1 letter");
name = consoleReader.readLine();
}
net.send(name + "\n");
} catch (IOException e) {
LOGGER.error(e);
}
}
private void readMessage() {
readMessage = new Thread(() -> {
String str = net.receive();
while (net.isConnected()) {
if ("full".equals(str)) {
System.out.println("server is full");
running.set(false);
break;
} else {
System.out.println(str);
str = net.receive();
}
}
net.offService();
}, "readMessage");
readMessage.start();
}
private void writeMessage() {
writeMessage = new Thread(() -> {
while (running.get()) {
String userWord;
try {
String time = dTime.getHour() + ":" + dTime.getMinute() + ":" + dTime.getSecond();
userWord = consoleReader.readLine();
if (userWord.equals("quit")) {
net.send(userWord + "\n");
ClientAmountGenerator.decrement();
running.set(false);
} else {
net.send("(" + time + ") " + name + " says : " + userWord + "\n");
}
} catch (IOException e) {
LOGGER.error(e);
}
}
net.offService();
}, "writeMessage");
writeMessage.start();
}
}
I want to change running to "false",so the writeMessage thread wont work if it gets message "full" from the server

How to fix 'Server sending data faster than client can handle, server freezes'

I'm using a java server to facilitate online multiplayer in my game made with GameMaker Studio, the players will send data to the java server which will process the data and send it to the players. The problem is that when a player with a slow internet connection is not being able to handle the amount of data being send to it, it will cause the server to freeze for all players (the server will no longer process any data send by other players).
I have simulated slow internet speeds by using NetLimiter and setting the download speed of one laptop at 5 kb/s, while maintaining proper speed at other laptops. I have tried to send ACK packets from the java server to the client and if it doesn't respond in 1 second no more data will be send to that client (and eventually the client will be kicked). This has reduced the chance of freezing the server, but it will still happen occasionally.
Main.java
import java.net.Socket;
import java.net.SocketAddress;
import java.net.InetSocketAddress;
import java.io.IOException;
import java.util.HashMap;
import java.net.ServerSocket;
import java.net.SocketTimeoutException;
public class Main
{
static ServerSocket serverSocket_;
static HashMap<String, ServerInformation> servers_;
static int verboseLevel_;
static int threadTimeout_;
static int masterPort_;
static int serverNumber_;
static int socketTimeOut_;
static {
Main.serverSocket_ = null;
Main.servers_ = new HashMap<String, ServerInformation>();
Main.verboseLevel_ = 5;
Main.threadTimeout_ = 10;
Main.masterPort_ = 6510;
Main.serverNumber_ = 1;
Main.socketTimeOut_ = 6000;
}
public static void main(final String[] args) {
try {
setupServerAndCleanup(Main.masterPort_);
while (true) {
handleIncomingConnection();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
static void setupServerAndCleanup(final int port) throws IOException {
(Main.serverSocket_ = new ServerSocket()).setReuseAddress(true);
Main.serverSocket_.bind(new InetSocketAddress(Main.masterPort_));
System.out.println("Server socket up and running on port " + Main.masterPort_);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
if (Main.serverSocket_ != null) {
try {
Main.serverSocket_.close();
System.out.println("Server socket closed, port released");
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}));
}
static void handleIncomingConnection() throws IOException {
final Socket clientSocket = Main.serverSocket_.accept();
clientSocket.setSoTimeout(Main.socketTimeOut_);
final ClientThread client = new ClientThread(clientSocket);
client.start();
}
}
ClientThread.java
Case 1 is the part dealing with sending data to the clients, in particular this line:
thread2.out_.print(msg);
If more data is being send than one client can handle the server will freeze for all other clients as well.
import java.util.Iterator;
import java.io.IOException;
import java.io.Reader;
import java.io.InputStreamReader;
import java.util.regex.Pattern;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class ClientThread extends Thread
{
Socket clientSocket_;
String clientIp_;
String serverIp_;
ServerInformation server_;
PrintWriter out_;
BufferedReader in_;
boolean prepareTermination_;
boolean terminated_;
private static final Pattern numberPattern;
static {
numberPattern = Pattern.compile("\\d+");
}
public ClientThread(final Socket sock) {
this.clientSocket_ = sock;
this.clientIp_ = this.clientSocket_.getRemoteSocketAddress().toString();
this.serverIp_ = null;
this.server_ = null;
this.prepareTermination_ = false;
this.terminated_ = false;
}
#Override
public void run() {
try {
this.out_ = new PrintWriter(this.clientSocket_.getOutputStream(), true);
this.in_ = new BufferedReader(new InputStreamReader(this.clientSocket_.getInputStream()));
long lastActionTime = System.currentTimeMillis();
while (true) {
if (this.in_.ready() || System.currentTimeMillis() - lastActionTime >= 1000 * Main.threadTimeout_) {
if (System.currentTimeMillis() - lastActionTime >= 1000 * Main.threadTimeout_) {
//this.logDebugMessage(3, "Thread was killed due to prolonged inactivity (" + Main.threadTimeout_ + " seconds)");
this.terminateThread();
return;
}
final String tempInputLine;
if(((tempInputLine = this.in_.readLine()) == null )){
this.terminateThread(); //end thread
return;
}
else
{
lastActionTime = System.currentTimeMillis();
final String inputLine = tempInputLine.trim();
if (ClientThread.numberPattern.matcher(inputLine).matches()){
final int val = Integer.parseInt(inputLine);
switch (val) {
case 1: { //send data to other players
final int parseCount = Integer.parseInt(this.in_.readLine().trim());
final StringBuilder msg = new StringBuilder();
for (int j = 0; j < parseCount; ++j) {
msg.append(String.valueOf(this.in_.readLine().trim()) + "|");
}
for (final ClientThread thread2 : this.server_.ipToClientThread_.values()) {
if (thread2 != this) {
thread2.out_.print(msg);
thread2.out_.flush();
}
}
//this.logDebugMessage(5, "Packet for others: '" + msg.toString() + "'");
break;
}
case 2: { //remove game server
//this.logDebugMessage(1, "A game server has been deleted, ip: " + ipServer);
Main.servers_.remove(this.server_.ip_);
this.serverIp_ = null;
for (final ClientThread thread : this.server_.ipToClientThread_.values()) {
thread.prepareTermination_ = true;
}
this.terminateThread();
return;
}
case 3: { //connect new client
final String ipServer = this.in_.readLine().trim();
final String ipClient = this.in_.readLine().trim();
this.logDebugMessage(1, "A client wishes to connect to a server, client: " + ipClient + ", server: " + ipServer);
final ServerInformation info = Main.servers_.getOrDefault(ipServer, null);
if (info == null) {
System.out.println("Connection to the server failed, no such server in the server list");
this.out_.print("*" + 1 + "|" + 1 + "~" + "|");
this.out_.flush();
break;
}
this.server_ = info;
this.server_.ipToClientThread_.put(ipClient, this);
this.logDebugMessage(1, "Connection success");
this.logDebugMessage(5,"Map: " + this.server_.ipToClientThread_);
this.out_.print("*" + 1 + "|" + 2 + "~" + "|");
this.out_.flush();
break;
}
case 4: { //disconnect client
final String ipClient = this.in_.readLine().trim();
this.server_.ipToClientThread_.remove(ipClient);
this.logDebugMessage(1, String.valueOf(ipClient) + " disconnected from the server at " + this.server_.ip_);
this.serverIp_ = null;
this.terminateThread();
return;
}
case 5: { //host create new game
if (Main.serverNumber_ > 1000000) {
Main.serverNumber_ = 10;
}
Main.serverNumber_ += 1;
final String ipServer = Integer.toString(Main.serverNumber_); //unique server number
final String ipHost = this.in_.readLine().trim(); //host
final String name = this.in_.readLine().trim(); //Server name
final String description = this.in_.readLine().trim(); //class
final String servervar1 = this.in_.readLine().trim(); //max players
final String servervar3 = this.in_.readLine().trim(); //current lap
final String servervar4 = this.in_.readLine().trim(); //total laps
final String servervar5 = this.in_.readLine().trim(); //status
final String servervar6 = this.in_.readLine().trim(); //Password
final String servervar7 = this.in_.readLine().trim(); //Online version
final String servervar8 = this.in_.readLine().trim(); //Game server
final long servervar9 = System.currentTimeMillis(); //server creation time
//this.logDebugMessage(1, "A game server has been registered, ip: " + ipServer + ", name: " + name + ", description: " + description + ", servervar1: " + servervar1);
final ServerInformation gameServer = new ServerInformation(name, servervar1, servervar3, servervar4, servervar5, servervar6, servervar7, servervar8, servervar9, ipHost, ipServer, this.clientSocket_, this.out_, this.in_);
gameServer.description_ = description;
gameServer.ipToClientThread_.put(ipHost, this);
this.server_ = gameServer;
Main.servers_.put(ipServer, gameServer);
this.serverIp_ = ipServer;
break;
}
default: {
this.logDebugMessage(0, "Unrecognized case: '" + inputLine + "', " + val);
break;
}
}
}
else if (inputLine.length() > 0) {
this.logDebugMessage(0, "Unformated '" + inputLine + "'");
if (this.server_ != null) {
this.server_.out_.print(inputLine);
this.server_.out_.flush();
}
}
if (this.prepareTermination_) {
this.terminateThread();
return;
}
continue;
}
}
}
}
catch (SocketTimeoutException e) {
e.printStackTrace();
try {
this.terminateThread();
}
catch (IOException e2) {
e2.printStackTrace();
}
}
catch (IOException e3) {
e3.printStackTrace();
try {
this.terminateThread();
}
catch (IOException e4) {
e4.printStackTrace();
}
}
}
//debug messages
void logDebugMessage(final int requiredVerbose, final String msg) {
if (Main.verboseLevel_ >= requiredVerbose) {
System.out.println("[" + this.clientIp_ + "] " + msg);
}
}
//terminate thread
void terminateThread() throws IOException {
if (!this.terminated_) {
if (this.serverIp_ != null) {
Main.servers_.remove(this.serverIp_);
}
this.clientSocket_.close();
this.in_.close();
this.out_.close();
this.logDebugMessage(3, "Cleanup successful");
this.terminated_ = true;
}
}
}
How to avoid the server from freezing if more data is being send to a client than it can handle, so that the server can continue sending data to the other clients?
Edit
So I have tried using ExecutorService, but I must be doing something completely wrong because no data is being send by the java server.
for (final ClientThread thread2 : this.server_.ipToClientThread_.values()) {
if (thread2 != this) {
executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
thread2.out_.print(msg);
thread2.out_.flush();
}
});
executorService.shutdown();
}
}
It would be great if you could show me how to implement ExecutorService the right way.
If a delay in the client processing doesn't matter, this part should be done in a distinct flow execution for each client :
for (final ClientThread thread2 : this.server_.ipToClientThread_.values()) {
thread2.out_.print(msg);
thread2.out_.flush();
}
For example :
for (final ClientThread thread2 : this.server_.ipToClientThread_.values()) {
if (thread2 != this) {
new Thread(()-> {
thread2.out_.print(msg);
thread2.out_.flush();
})
.start();
}
}
Note that creating Threads has a cost. Using ExecutorService could be a better idea.

Categories