We have a java socket program where the server gets data from many devices and works fine. At times the server needs to send some command to the devices. When it sends individual commands it works fine. The problem comes when it sends multiple commands, only the first one is successful. We cant figure out why the rest fails. Below is the snippet showing how the message is sent. Should I set a delay after a message is sent?
public static void main(String[] args) {
new sServer7888();
}
sServer7888() {
try{
final ServerSocket serverSocketConn = new ServerSocket(7888);
while (true){
try{
Socket socketConn1 = serverSocketConn.accept();
new Thread(new ConnectionHandler(socketConn1)).start();
}
catch(Exception e){
e.printStackTrace(System.out);
}
}
}
catch (Exception e) {
e.printStackTrace(System.out);
}
}
class ConnectionHandler implements Runnable {
private Socket receivedSocketConn1;
ConnectionHandler(Socket receivedSocketConn1) {
this.receivedSocketConn1=receivedSocketConn1;
}
public void run() {
while ((nextChar=readIn1.read()) != -1) {
completeMessage += (char) nextChar;
if (nextChar == '*')
{
String[] splitResult = completeMessage .split(",");
String header=splitResult[0].trim().substring(0,4);
if((header.equals("$ACK")){
//update the message sent from the server as already acknowledge.
}
else{
//run query to find if there are any message to be sent out to the devices
while(rsOC1.next()){
commandText = rsOC1.getString("commandText");
writeOut1.write(commandText);
writeOut1.write("\r\n");
writeOut1.flush();
}
//now process the normal message receive from the devices.
}
completeMessage="";
}
}
}
}
If your device is sending ACK on Every message and Server is able to receive it then you can proceed in following way with your server side program.
EDIT
I have updated the code as per the requirement analysis. Let me know if any discrepancy is found after implementing it.
Thread.sleep(1000) is not the reliable solution for above case because
we are not knowing how long the device might take to execute previous
command sent by Server .
public void run()
{
int i = -1;
ArrayList<String> list = new ArrayList<String>();
while ((nextChar=readIn1.read()) != -1)
{
boolean isCompleteMessage = readMessage(nextChar);
if (isCompleteMessage)
{
String[] splitResult = completeMessage .split(",");
String header=splitResult[0].trim().substring(0,4);
if((header.equals("$ACK"))
{
String id = null;
if (i != -1)
{
id = list.get(i);
id = id.substring(0,id.indexOf("^"));
}
//update the message sent from the server as already acknowledge using id extracted above.
if ( i == 0)
{
list.remove(i);
if (list.size() == 0)
{
i = -1;
}
else
{
commandText = list.get(i);
writeOut1.write(commandText.substring((commandText.indexOf("^")) + 1));
writeOut1.write("\r\n");
writeOut1.flush();
}
}
}
else
{
//process here the normal message receive from the devices.
if (i == -1)
{
list = getRecords();
if (list.size() > 0)
{
i = 0;
commandText = list.get(i);
writeOut1.write(commandText.substring((commandText.indexOf("^")) + 1));
writeOut1.write("\r\n");
writeOut1.flush();
}
}
else
{
commandText = list.get(i);
writeOut1.write(commandText.substring((commandText.indexOf("^")) + 1));
writeOut1.write("\r\n");
writeOut1.flush();
}
}
completeMessage = "";
}
}
}
public boolean readMessage(int nextChar)
{
completeMessage += (char)nextChar;
if (((char)nextChar) == '*')
{
return true;
}
else
{
return false;
}
}
//Retreive all commands from database and returns the ArrayList containing those commands.
public ArrayList<String> getRecords()
{
ArrayList<String> list = new ArrayList<String>();
Statement stat = null;
ResultSet rsOC1 = null;
try
{
stat = con.createStatement();
rsOC1 = stat.executeQuery("Query for message retrieval from database");
while (rsOC1.next())
{
String sElement = rs0C1.getString("commandID") + "^" + rs0C1.getString("commandText");
list.add(sElement);
}
}
catch (Exception ex){}
finally
{
if (rs0C1 != null)
{
try
{
rs0C1.close();
} catch () {}
}
if (stat != null)
{
try
{
stat.close();
} catch () {}
}
return list;
}
}
Related
Actually I make an update through Bluetooth. In first time I erase the memory bank and then I write an hexa File on it.
But half the time an update will don't work correctly, for every data I transfer the first writeCharacteristic will return false.
It happen on an entire update half the time.
I try in debug mode but the method never return false in that case, of course it's probably a delay problem, but I can't increase the time.
This is my code for send my data :
public void sendTX(final byte[] sMessage) {
BluetoothGattService service = mBluetoothGatt.getService(UUID_SERVICE_SERIAL);
if (service != null && sMessage != null) {
Log.d(TAG,"sMessage : " + sMessage);
final BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID_TX);
if (characteristic != null) {
Thread thread = new Thread() {
public void run() {
if (sMessage.length > 20) {
for (int i = 0; i < sMessage.length; i += 20) {
byte[] byteArraySplit = Arrays.copyOfRange(sMessage, i, i + 20 < sMessage.length ? i + 20 : sMessage.length);
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
characteristic.setValue(byteArraySplit);
while(!mBluetoothGatt.writeCharacteristic(characteristic)) {
try {
TimeUnit.MILLISECONDS.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} else {
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
characteristic.setValue(sMessage);
while(!mBluetoothGatt.writeCharacteristic(characteristic)){
try {
TimeUnit.MILLISECONDS.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
thread.start();
} else {
Log.d(TAG, "UUID TX null");
}
} else {
Log.d(TAG, "Service BLE null");
}
}
And this is the code of the native writeCharacteristic method :
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
&& (characteristic.getProperties() &
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false;
if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false;
BluetoothGattService service = characteristic.getService();
if (service == null) return false;
BluetoothDevice device = service.getDevice();
if (device == null) return false;
synchronized(mDeviceBusy) {
if (mDeviceBusy) return false;
mDeviceBusy = true;
}
try {
mService.writeCharacteristic(mClientIf, device.getAddress(),
characteristic.getInstanceId(), characteristic.getWriteType(),
AUTHENTICATION_NONE, characteristic.getValue());
} catch (RemoteException e) {
Log.e(TAG,"",e);
mDeviceBusy = false;
return false;
}
return true;
}
Never use timeouts to try to workaround this issue. The proper way is to wait for the callback and then perform the next request. See Android BLE BluetoothGatt.writeDescriptor() return sometimes false.
I'm trying to make simple telegram bot on Java.
The question is: how can I receive messages in a loop, when the user typed /start? I have already some
#Override
public void onUpdateReceived(Update update) {
Message msg = update.getMessage();
String txt = msg.getText();
if (txt.equals("/start")) {
sendMsg(msg, "Привет, меня зовут бот " + name + "!");
showHelp(msg);
run(msg, update);
} else if (txt.equals("/help")) {
showHelp(msg);
}
}
Here's showhelp:
private void showHelp(Message msg) {
try {
String inAbout = ReadFile.readFileInString(this.about);
sendMsg(msg, inAbout);
} catch (Exception ex) {
ex.printStackTrace();
}
}
sendMsg:
private void sendMsg(Message msg, String text) {
SendMessage s = new SendMessage();
s.setChatId(msg.getChatId());
s.setText(text);
try {
execute(s);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
In Run I want to read questions from data and wait for users answer, check if correct and do it in loop. In the end show how many he answered correct.
public void run(Message msg, Update update) {
try {
List<String> data = ReadFile.readFileInList(this.getData());
List<String> dataAnswers = ReadFile.readFileInList(this.answers);
this.sizeOfAnswers = data.size();
for (int i = 0; i < data.size(); i++) {
String line = data.get(i);
sendMsg(msg, line);
String inAnswer = update.getMessage().getText();
String rAns = dataAnswers.get(i);
boolean flag = checkAnswer(inAnswer, rAns);
if (flag) {
this.currentUser.incrementScore();
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
String finalString = "Поздравляю, ты ответил на " + this.currentUser.getScore() + "/" + this.sizeOfAnswers
+ " вопросов!";
sendMsg(msg, finalString);
}
}
Also here is maybe some multi user problems. How should I do it? Now it's showing all questions in one second without waiting for an answer.
How it's working now
First some Information regarding my Setup.
I have a S8 Cellphone, where i run this App, based upon the AR-Devkit demo from Google.
public void closeSocket(DatagramSocket socket) {
if (socket != null && socket.isConnected() ) {
while (!socket.isConnected()) {
socket.disconnect();
try {
Thread.sleep(SpringAR.TIME_OUT_IN_BROADCAST);
} catch (InterruptedException e) {
Log.d(SpringAR.protocollDebugLogPrefix, " Socket Closing interrupted");
e.printStackTrace();
}
}
}
if (socket != null && !socket.isClosed()) {
socket.close();
while (!socket.isClosed()) {
try {
Thread.sleep(SpringAR.TIME_OUT_IN_BROADCAST);
} catch (InterruptedException e) {
Log.d(SpringAR.protocollDebugLogPrefix, " Socket Closing interrupted");
e.printStackTrace();
}
}
}
}
public DatagramSocket createSocket(InetAddress ipAddress, int port) {
try {
DatagramSocket socket = new DatagramSocket(null);
InetSocketAddress address = new InetSocketAddress(ipAddress, port);
socket.setReuseAddress(true);
socket.bind(address);
return socket;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public DatagramSocket getBroadcastListenerSocket() throws IOException {
InetSocketAddress anyAdress = new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 9000);
DatagramSocket socket = new DatagramSocket(null);
socket.setSoTimeout(30);
socket.setReuseAddress(true);
socket.bind(anyAdress);
return socket;
}
public DatagramSocket getBroadcastSenderSocket(DatagramSocket oldSocket) {
DatagramSocket socket = null;
try {
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
socket = getSocket(oldSocket, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, null);
socket.setBroadcast(true);
socket.setSoTimeout(SpringAR.TIME_OF_FRAME_IN_MS);
} catch (IOException e) {
e.printStackTrace();
}
return socket;
}
public DatagramSocket getSocket(DatagramSocket oldSocket, InetAddress ipAddress, int port, InetAddress targetAddress) {
if (oldSocket != null ) {
closeSocket(oldSocket);
}
DatagramSocket socket = null;
try {
socket = createSocket(ipAddress, port);
socket.setBroadcast(false);
socket.setSoTimeout(SpringAR.TIME_OF_FRAME_IN_MS);
if (targetAddress != null)
socket.connect(targetAddress, port);
} catch (SocketException e) {
e.printStackTrace();
}
return socket;
}
public class DatagramReciever extends Thread {
private String datagramToSend = "";
private boolean newDatagramToSend = false;
private DatagramPacket snd_packet;
DatagramSocket senderSocket = null;
DatagramSocket listenerSocket = null;
private DatagramSocket broadCastListenerSocket;
//Buffer gettters and setters
private int writeBuffer = 0;
private SpringAR.comStates oldState;
int getReadBuffer() {
if (writeBuffer == 1) return 0;
return 1;
}
void switchBuffer() {
recieveByteIndex = 0;
writeBuffer = getReadBuffer();
}
public String dbg_message = "";
//Management Communication Headers
public void kill() {
closeSocket(senderSocket);
closeSocket(listenerSocket);
closeSocket(broadCastListenerSocket);
}
public void run() {
try {
initializeBroadcastConnection();
while (true) {
//Recieving Datagramm
DatagramPacket rcv_packet = new DatagramPacket(rcv_message[writeBuffer], rcv_message[writeBuffer].length);
boolean NewMessageArrived = true;
try {
listenerSocket.receive(rcv_packet);
} catch (SocketTimeoutException e) {
NewMessageArrived = false;
}
//Watchdog
handleWatchDogTimer(State);
//TODO Delete String conversion
if (NewMessageArrived) {
dbg_message = new String(rcv_message[writeBuffer], 0, rcv_packet.getLength(), "US-ASCII");
Log.d(SpringAR.dataDebugLogPrefix, "" + rcv_packet.getAddress().getHostAddress() + ": " + dbg_message.trim() + " of " + rcv_packet.getLength() + "length ");
}
if (validatePackageSender(rcv_packet)) {
connectionStateMachine(rcv_message, rcv_packet);
}
//Sending Datagram
if (newDatagramToSend && hostIpAddress != null) {
//Log.d(SpringAR.protocollDebugLogPrefix, "Server sending: " + datagramToSend);
byte[] snd_message = datagramToSend.getBytes();
try {
snd_packet = packSendPackageByState(snd_message);
assert (snd_packet != null);
senderSocket.send(snd_packet);
newDatagramToSend = false;
} catch (IOException e1) {
e1.printStackTrace();
//causes Caused by: android.system.ErrnoException: sendto failed: EINVAL (Invalid argument)
Log.e(SpringAR.protocollDebugLogPrefix, "Server Error in State: " + State.name());
break;
}
}
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
private void initializeBroadcastConnection() throws IOException {
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
senderSocket = getSocket(null, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, null);
broadCastListenerSocket = getBroadcastListenerSocket();
listenerSocket = broadCastListenerSocket;
Log.d(SpringAR.protocollDebugLogPrefix, "initializeBroadcastConnection completed");
}
// handles management traffic like configurstion files
private void connectionStateMachine(byte[][] payload, DatagramPacket rcv_packet) throws IOException {
//Reset triggered by Host
if (comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveResetHeaderByte) != SpringAR.STRING_NOT_FOUND) {
State = SpringAR.comStates.STATE_resetCommunication;
}
Log.d(SpringAR.protocollDebugLogPrefix, "ConnectionStateMachine: " + State.name());
switch (State) {
case STATE_resetCommunication: {
messageCounter = 0;
listenerSocket = broadCastListenerSocket;
hostIpAddress = comonUtils.getBroadcastAddress(context);
senderSocket = getBroadcastSenderSocket(senderSocket);
setSendToSpringMessage(SpringAR.sendResetHeader);
State = SpringAR.comStates.STATE_broadCastHeader;
return;
}
case STATE_broadCastHeader: {
if (comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveHostReplyHeaderByte) != SpringAR.STRING_NOT_FOUND) {
Log.d(SpringAR.protocollDebugLogPrefix, " Host Reply Header recieved");
//Extract the hostIp
String hostIpAdressAsString = new String(payload[writeBuffer]);
hostIpAdressAsString = hostIpAdressAsString.replace(SpringAR.recieveHostReplyHeader, "").trim();
Log.d(SpringAR.dataDebugLogPrefix, hostIpAdressAsString);
hostIpAddress = InetAddress.getByName(hostIpAdressAsString);
//Set Connection from broadcast to target
ARDeviceAddress = InetAddress.getByName(comonUtils.getIPAddress(true));
Log.d(SpringAR.protocollDebugLogPrefix, " New Device Adress " + ARDeviceAddress);
senderSocket = getSocket(senderSocket, ARDeviceAddress, SpringAR.UDP_SERVER_PORT, hostIpAddress);
listenerSocket = senderSocket;
State = SpringAR.comStates.STATE_sendCFG;
return;
}
setSendToSpringMessage(SpringAR.sendBroadcasteHeader);
delayByMs(SpringAR.TIME_OUT_IN_BROADCAST);
return;
}
case STATE_sendCFG: {
if ( SpringAR.STRING_NOT_FOUND != comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveCFGHeaderByte )) {
State = SpringAR.comStates.STATE_sendRecieveData;
return;
}
setSendToSpringMessage(SpringAR.formConfigurationMessage());
return;
}
case STATE_sendRecieveData: {
if ( SpringAR.STRING_NOT_FOUND != comonUtils.indexOf(payload[writeBuffer], SpringAR.recieveDataHeaderByte)) {
writeRecievedDataToBuffer(payload[writeBuffer], rcv_packet.getLength());
}
break;
}
default:
Log.d(SpringAR.protocollDebugLogPrefix, "Connection State Machine invalid state");
}
}
https://github.com/PicassoCT/arcore-android-sdk/blob/6c9b48a3d520e039cd48bc2af7354ccdec857736/arcore-android-sdk/samples/hello_ar/app/src/main/java/com/google/ar/core/examples/app/common/tcpClient/Server.java
All the testing is happening in a home-WiFi Setup, where the desktop with the host-application is directly attached to the WiFi-Router.
What is working thus far:
The device can broadcast its presence.
The host can broadcast its configuration.
The Device can not communicate from IP to IP on the host. Both sides have fixed IP set.
I can communicate with the App PacketSender with the host-Application, and ruled a failure on its part out.
I also built a smaller debug-loop, to only send udp-packets back and forth, which also worked.
Thank you for your time
Change this line:
socket.setSoTimeout(30);
to
socket.setSoTimeout(1000);
You've got a fairly complex state machine going here, and it's difficult to discern what is happening without having logs to look at. I would summarize your state machine like this:
Broadcast a configuration message
Spend 30ms listening for a response
If no response is received, block for SpringAR.TIME_OF_FRAME_IN_MS (not included in your code; I assume it is 1000ms), and loop back to #1
If a response was received, send a reply directly to the peer, and go to #2
#4 is the step that isn't happening. The likely reason (based on the Wireshark dump) is that it's taking 68ms for ARDevice's response to reach "Host". You only gave it 30ms. There could be a number of reasons it's taking so long, but that's beyond the scope of your question.
server will run the array which disconnect user after client press connect button
public void run() {
String message, connect = "Connect", disconnect = "Disconnect", chat = "Chat" ;
String[] data;
try {
while ((message = reader.readLine()) != null) {
outputTextArea.append("Received: " + message + "\n");
data = message.split(":");
for (String token:data) {
outputTextArea.append(token + "\n");
}
if (data[2].equals(connect)) {
tellEveryone((data[0] + ":" + data[1] + ":" + chat));
userAdd(data[0]);
} else if (data[2].equals(disconnect)) {
tellEveryone((data[0] + ":has disconnected." + ":" + chat));
userRemove(data[0]);
} else if (data[2].equals(chat)) {
tellEveryone(message);
} else {
outputTextArea.append("No Conditions were met. \n");
}
} // end while
} // end try
catch (Exception ex) {
outputTextArea.append("Lost a connection. \n");
ex.printStackTrace();
clientOutputStreams.remove(client);
} // end catch
} // end run()
} // end class ClientHandler
public void userAdd (String data) {
String message, add = ": :Connect", done = "Server: :Done", name = data;
outputTextArea.append("Before " + name + " added. \n");
onlineUsers.add(name);
outputTextArea.append("After " + name + " added. \n");
String[] tempList = new String[(onlineUsers.size())];
onlineUsers.toArray(tempList);
for (String token:tempList) {
message = (token + add);
tellEveryone(message);
}
tellEveryone(done);
}
public void userRemove (String data) {
String message, add = ": :Connect", done = "Server: :Done", name = data;
onlineUsers.remove(name);
String[] tempList = new String[(onlineUsers.size())];
onlineUsers.toArray(tempList);
for (String token:tempList) {
message = (token + add);
tellEveryone(message);
}
tellEveryone(done);
}
public void tellEveryone(String message) {
// sends message to everyone connected to server
Iterator it = clientOutputStreams.iterator();
while (it.hasNext()) {
try {
PrintWriter writer = (PrintWriter) it.next();
writer.println(message);
writer.flush();
outputTextArea.setCaretPosition(outputTextArea.getDocument().getLength());
} // end try
catch (Exception ex) {
outputTextArea.append("Error telling everyone. \n");
} // end catch
} // end while
} // end tellEveryone()
Client Side:
ArrayList<String> userlist = new ArrayList();
public class IncomingReader implements Runnable{
public void run(){
String stream;
String[] data;
String done = "Done", connect = "connect", disconnect = "Disconnect", chat ="Chat";
try {
while ((stream = reader.readLine()) != null){
data = stream.split("!");
if (data[2].equals(chat)) {
chatTextArea.append(data[0]+":"+ data[1]+"\n");
chatTextArea.setCaretPosition(chatTextArea.getDocument().getLength());
} else if (data[2].equals(connect)){
chatTextArea.removeAll();
userAdd(data[0]);
} else if (data[2].equals(disconnect)){
userRemove(data[0]);
} else if (data[2].equals(done)){
onlineuserlist.setText("");
writeUsers();
userlist.clear();
}
}
}catch(Exception ex){
}
}
}
private void userAdd(String data) {
userlist.add(data);
}
private void userRemove(String data) {
chatTextArea.append(data +"has disconnected.\n");
}
private void writeUsers() {
String[] tempList = new String[(userlist.size())];
userlist.toArray(tempList);
for (String token:tempList) {
onlineuserlist.append(token +"\n");
}
}
public void sendDisconnect(){
String bye =(username + ": :Disconnect");
try{
writer.println(bye);
writer.flush();
} catch (Exception ex){
chatTextArea.append("could not send Disconnect Message.\n");
}
}
public void Disconnect(){
try{
chatTextArea.append("Disconnected.\n");
sock.close();
} catch (Exception ex){
chatTextArea.append("Failed to disconnect. \n");
}
isConnected = false;
usernameField.setEditable(true);
onlineuserlist.setText("");
}
}
after start the server and client press the connect button, it will show which user has connected but it also disconnect the connection and got this error.
java.lang.ArrayIndexOutOfBoundsException: 2
at chatsystemserver.ServerSide$ClientHandler.run(ServerSide.java:55)
at java.lang.Thread.run(Thread.java:745)
It would appear that you don't have an array of size == 3 when you do you split. You might want to do some array size checking before you access "data[2]".
I'm working on a client-server application with two modules:
1). Registry: All servers in the network register their IP and port they are listening to with the registry.
2). Messaging node: These are also servers, which communicate with each other in a round of messages, once they receive the command from the registry. A messaging node will only send messages to 1 node at a time, but may receive from multiple nodes.
The registry sends a list of available (registered) nodes to all other servers, and upon receiving this list, the nodes start exchanging messages with each other.
I was able to get the registry part working, and the nodes are able to register themselves. Also, the nodes successfully receive the nodes list from the registry and able to start exchanging messages. How ever, the messaging nodes are not able to receive all the messages being sent.
Here's the messaging node part:
public class MessagingNode {
// Constructor
public MessagingNode(String registryHost, int registryPort) {
try {
registryHostname = InetAddress.getByName(registryHost).getHostAddress();
} catch (Exception e) {
System.out.println("Can't resolve Registry hostname!");
}
registryPortNumber = registryPort;
// Start the node server
try {
nodeServerSocket = new ServerSocket(0);
}
catch (Exception e) {
System.out.println("Can't start node server!");
}
// Store the MessagingNode server port and IP address
try {
nodeIpAddress = InetAddress.getLocalHost().getHostAddress();
} catch(Exception e) {
System.out.println("Can't get localhost");
}
nodePortNumber = nodeServerSocket.getLocalPort();
//System.out.println("Node Port:"+nodePortNumber);
// Initialize trackers
sendTracker = 0;
receiveTracker = 0;
sendSummation = 0;
receiveSummation = 0;
sending = false;
}
// Start the NodeServer to listen for other nodes
public void startNodeServer() {
if(!isRunning) {
isRunning = true;
consoleListener();
while(MessagingNode.this.isRunning) {
Socket clientSocket = null;
try {
clientSocket = nodeServerSocket.accept();
openClient(clientSocket);
}
catch(IOException e) {
e.printStackTrace();
}
}
}
}
// Messaging nodes receiving
public void openClient(final Socket socket) {
Thread clientThread = new Thread() {
public void run() {
int count = 0;
try {
byte[] messagePayload = new byte[64];
InputStream in = socket.getInputStream();
DataInputStream din = new DataInputStream(in);
//BufferedReader br = new BufferedReader(new InputStreamReader(in));
while(din.read(messagePayload) > -1) {
//count++;
int type = InterpretMessage.getMessageType(messagePayload);
if(type == MessageTypes.MESSAGING_NODES_LIST) {
trimNodeList(messagePayload);
System.out.println("Node list Received!");
dataThread();
}
else {
handleIncomingPayload(messagePayload);
}
}
//System.out.println("Input connection closed after :" + count);
//System.out.println("Listener Closed!");
//in.close();
//socket.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
};
clientThread.start();
try {
clientThread.join();
}
catch(Exception e) {
e.printStackTrace();
}
}
public void dataThread() {
Thread t = new Thread() {
public void run() {
sendData();
}
};
t.start();
try {
t.join();
}
catch(Exception e) {
e.printStackTrace();
}
}
public void sendData() {
// pick a node
int size = messagingNodesList.size();
int index = (int)(Math.random() * size);
//System.out.println("Node being contacted:" + messagingNodesList.get(index));
String details = messagingNodesList.get(index);
String[] str = details.split(" ");
try {
Socket socket = new Socket(str[0], Integer.parseInt(str[1]));
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
for(int i= 0; i < 5; i++) {
CommMessage outgoing = new CommMessage();
byte[] msg = outgoing.marshall();
out.write(msg, 0, msg.length);
System.out.println("Sending number:" + outgoing.number);
out.flush();
}
out.close();
//closeConnection = true;
}
catch(IOException e) {
e.printStackTrace();
}
}
// Remove Node's information
public void trimNodeList(byte[] incoming) {
// Removes the current node's information from the list recieved from registry
}
// Update trackers
public void handleIncomingPayload(byte[] payload) {
CommMessage msg = new CommMessage(payload);
msg.unmarshall();
System.out.println("Receiving Number:"+msg.number);
//synchronized(this) {
receiveSummation += msg.number;
receiveTracker += 1;
//}
}
// Console Listener
public void consoleListener() {
Thread listener = new Thread() {
public void run() {
// listen for keyboard instructions
}
};
listener.start();
}
public static void main(String[] args) {
MessagingNode node = new MessagingNode(args[0], Integer.parseInt(args[1]));
node.connectRegistry();
node.startNodeServer();
//node.deregisterNode();
//node.deregisterNode();
//node.sendBurst();
// Launch the console Listener Thread
// Initiate rounds of messaging
}
}
The problem is somewhere in the receiving portion I'm assuming. I tried using using synchronized on the sendData method as someone pointed out it could be a concurrency issue but it didn't help. I'm still not able to receive all messages. Any insights will be really helpful.
Thanks.