Android multicast.receive() dying and no exception - java

I am making a multicast messenger for part of my masters degree. I have previously successfully made this exact same implementation on desktop Java and had no issues what so ever. HOWEVER, when I run the code from Android problems occur. I can send to the multicast group just fine, but receiving does not work.
The output simply stops in the console after "2".
The application just stops giving me feedback on the line that is socket.receive()I am getting no exceptions either.
Below I have attached the class that I am using to receive the messages.
For the full android implementation I have the dropbox link available at: https://www.dropbox.com/s/vuoifbxqk01c079/MyApplication.zip?dl=0
It is pretty rough, but it does successfully send, just not receive.
public class EMMS extends Thread{
MulticastSocket socket;
InetAddress ip;
byte [ ] buffer;
int usedPort;
public boolean isSending;
private MainActivity view;
public EMMS(MainActivity view, int port, String ipAddress){
try {
// Create Multicast socket
socket = new MulticastSocket(port);
usedPort = port;
// Set address to join
ip = InetAddress.getByName(ipAddress);
// join group
socket.joinGroup(ip);
System.out.println("Group Joined! ");
// create buffer
buffer = new byte[512];
isSending = false;
this.view = view;
}//end of try
catch (SocketException se){
System.out.println("Socket Exception : " + se); }
catch (IOException e) { System.out.println("Exception : " + e); }
}
public void run(){
try {
System.out.println("Incoming Message! ");
while (isSending == false) {
// Create and receive packet
System.out.println("1");
DatagramPacket dp = new DatagramPacket(buffer, buffer.length,ip, usedPort);
System.out.println("2");
socket.receive(dp);
System.out.println("3");
String str = new String(dp.getData());
System.out.println("4");
String ipAddress = dp.getAddress().getHostAddress();
System.out.println("5");
// Create string array of components
String[] data = str.split("##");
String senderName= data[2];
String sourceIP= ipAddress;
String typeOfEmergency=data[3];
String condition=data[0];
String instruction=data[1];
System.out.println("Incoming Message! ");
System.out.println(
"Sender: " + senderName + "\n" +
"Source IP: " + sourceIP + "\n" +
"Emergency Type: " + typeOfEmergency + "\n" +
"Condition: " + condition + "\n" +
"Instruction: " + instruction
);
// Create popup window
AlertDialog alertDialog = new AlertDialog.Builder(view).create(); //Read Update
alertDialog.setTitle("ALERT");
alertDialog.setMessage(
"Sender: " + senderName + "\n" +
"Source IP: " + sourceIP + "\n" +
"Emergency Type: " + typeOfEmergency + "\n" +
"Condition: " + condition + "\n" +
"Instruction: " + instruction
);
alertDialog.show(); //<-- See This!
}
}//end of try
catch (SocketException se){
System.out.println("Socket Exception : " + se); }
catch (IOException e) { System.out.println("Exception : " + e); }
}
public void disconnect() throws IOException{
socket.leaveGroup(ip);
}

Related

How to read data from LAN port and display on broweser applet? sock.receive(incoming);

It works upto sock.receive(incoming); On my browser under applet.
After sock.receive(incoming); This line it is stuck. Nothing is display.
Or No Error or exception is throw even it goes away from this line.
Please Help me. Thank you in advance :)
sorry for my bad an English
This is my code.
while(true)
{
System.out.println("Under While loop...");
if(incoming != null)
{
System.out.println("Data is not blank..." + incoming );
}
else
{
System.out.println("Data is blank..." + incoming );
}
sock.receive(incoming);
System.out.println("Hello..");
byte[] data = incoming.getData();
if(data != null)
{
System.out.println("Data is not blank...");
}
else
{
System.out.println("Data is blank...");
}
String s = new String(data, 0, incoming.getLength());
//echo the details of incoming data - client ip : client port - client message
System.out.println(incoming.getAddress().getHostAddress() + " : " + incoming.getPort() + " : " + s);
if(s != "" )
{
String R = incoming.getAddress().getHostAddress() + " : " + incoming.getPort() + " : " + s;
//lblResultTest.setText(R);
String[] words = s.split("&");
txtResult.setText(words[2]);
this.getAppletContext().showDocument( this.getDocumentBase() );
}
//s = "OK : " + s;
//DatagramPacket dp = new DatagramPacket(s.getBytes() , s.getBytes().length , incoming.getAddress() , incoming.getPort());
//sock.send(dp);
}
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}

Socket help in java

I have looked a lots of examples and have asked a few people but no one seems to be able to tell me what I am doing wrong on my listen sockets. Please help.
I am making a program that reads from 3 files and then sends data in sockets in threads.
here is every thing I have done
public class Main {
public static void main(String[] args) throws Exception{
//making all threads for A,B and C
Thread T_A = new Thread(new threads ("A"));
Thread T_B = new Thread(new threads ("B"));
Thread T_C = new Thread(new threads ("C"));
//starting the threads for A,B and C
T_A.start();
T_B.start();
T_C.start();
}
}
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class threads implements Runnable {
//making temps
String name;
int listen;
int send;
String line;
BufferedReader reader;
BufferedReader input;
boolean Listening=false;
boolean Sending=false;
PrintWriter output;
ServerSocket node_listen=null;
Socket node_send=null;
Socket node_rev=null;
public threads(String x){
//name of thead A,B or C
name=x;
}
#Override
public void run(){
try{
//openinng the conf file for thread
reader = new BufferedReader(new FileReader("conf" + name + ".txt"));
//this is for node A because it only sends info does not get info
if(name.equals("A")==true){
//making a socket to send on
System.out.println("Node " + name + " is starting");
send = Integer.parseInt(reader.readLine());
for(int temp=0;temp!=5;temp++)
{
temp=Checker(temp);
}
}
//this is for node B becuase it sends and gets info
else if(name.equals("B")==true){
//getting ports for send and listen
listen = Integer.parseInt(reader.readLine());
send = Integer.parseInt(reader.readLine());
System.out.println("Node " + name + " is starting");
Listening=setUpListen();
for(int temp=0;temp!=5;temp++)
{
temp=Checker(temp);
}
}
//node C only gets info
else if(name.equals("C")==true){
//geting listen port
listen = Integer.parseInt(reader.readLine());
System.out.println("Node " + name + " is starting");
Listening=setUpListen();
}
//sends and gets data until it has no more to send or get
while(Listening==true || Sending== true)
{
//while it needs to get data and was a node that gets data
if(Listening==true)
{
Listen();
}
//Has not sent terminate yet and is a sending node
if(Sending==true)
{
Send();
}
}
}
catch(IOException | NumberFormatException e)
{
System.out.println(e);
}
catch (InterruptedException ex)
{
Logger.getLogger(threads.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Node " + name + " has ended");
}
public boolean setUpConnection(){
try {
//making a socket for sending
System.out.println("Node " + name + " is setting up connection");
node_send = new Socket("hostname", send);
output = new PrintWriter(node_send.getOutputStream(),true);
} catch (UnknownHostException e) {
System.out.println("Error setting up socket connection: " + name + " :" + send);
return false;
} catch (IOException e) {
System.out.println("Error setting up socket connection: " + name + " " + e);
return false;
}
//telling the thread it is a sending thread
Sending=true;
System.out.println("Node " + name + " is ready for sending");
return true;
}
public boolean setUpListen(){
try{
//making socket for Listening
System.out.println("Node " + name + " is setting up listen");
nodeListen = new ServerSocket(listen);
System.out.println("Node " + name + " is trying to listen");
node_rev = node_listen.accept();
System.out.println("Node " + name + " NEVER GETS HERE");
input = new BufferedReader(new InputStreamReader(node_rev.getInputStream()));
} catch (UnknownHostException e) {
System.out.println("Error setting up socket connection: " + name + " :" + listen);
return false;
} catch (IOException e) {
System.out.println("Error setting up socket connection: " + name + " " + e);
return false;
}
//telling the thread it is a Listening thread
System.out.println("Node " + name + " is ready for listening");
return true;
}
public void Listen(){
try{
line = input.readLine();
//As long as something was sent and it was not terminate prints data
if(line.equals("terminate")==false&&line.equals("null")==false)
{
System.out.println("Node " + name + " received:" + line);
}
//When terminate was sent it no longer looks for data
if(line.equals("terminate"))
{
Listening=false;
node_listen.close();
node_rev.close();
input.close();
System.out.println("Node " + name + " done listening");
}
}catch (IOException e) {
System.out.println("Error Listening on connection: " + name + " " + e);
}
}
public void Send(){
try{
//reads in the data and sends it to node
line=reader.readLine();
System.out.println(line);
output.println(line);
//if the data sent was terminate then exit sending mode
if(line.equals("terminate")==true)
{
Sending=false;
node_send.close();
output.close();
System.out.println("Node " + name + " done sending");
}
}catch (IOException e) {
System.out.println("Error Sending on connection: " + name + " " + e);
}
}
public int Checker(int temp) throws InterruptedException{
boolean connected=setUpConnection();
if(connected==true)
{
//connected
temp=5;
}
return temp;
}
}
each conf file is setup like this
confA.txt
5002
This is a sample line of text for node A.
This is another sample line of text for node A.
Node B will be printing out these three lines for node A.
terminate
confB.txt
5002
5005
This is a sample line of text.
This is another sample line of text.
Node C will be printing out these three lines.
terminate
confC.txt
5005
That is the out put I get
run:
Node A is starting
Node A is setting up connection
Node B is starting
Node B is setting up listen
Node C is starting
Node C is setting up listen
Node B is trying to listen
Node C is trying to listen
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A has ended
The code never seems to get to the line System.out.println("Node " + name + " NEVER GETS HERE"); in the setUpListen();
Thanks
That is because ServerSocket.accept() blocks until an incoming connection is reported. The method returns the Socket.
So the next line (System.out.println("Node " + name + " NEVER GETS HERE")) is never executed until you get another network interface to connect to your listening ServerSocket.
I don't know exactly what it is you're trying to achieve, but you need to listen for incoming connections in an apart thread:
final ServerSocket serverSocket = createServerSocket();
new Thread(new Runnable() {
#Override
public void run() {
Socket socket = serverSocket.accept();
System.out.println("Incoming connection from " + socket.getInetAddress());
doSomethingWithSocket(socket);
}
}).start();
PS: Please persist with the Java Naming Conventions:
Classes should always start with an Uppercase letter;
Field names (or class attributes) should always start with a lowercase letter;
Method names should always start with a lowercase letter.
It turns out that my problem was node_send = new Socket("hostname", send); should have been node_send = new Socket("localhost", send);
I am dumb.
However I want to thank everyone for there help and pointers.
public class threads ?? Conventions please.
O.t:
Error setting up socket connection: C java.net.BindException: Address already in use
The port that setted up each listener on, is the same. (i.e Address already in use.)

Trying to create multiple sockets(connections) to a single port in java application but cannot create a NEW SOCKET

In the code below, I establish the first connection without issue however, when I come back around in my while statement (highlighted in BOLD text below) at the newSocket = serverSocket.accept(); line my program stops there. The objective is to allow multiple connections to one PORT. I'm in the middle of re-factoring an inherited application that has been working but only allowing one connection to one port at a time. This is my first crack at socket programming and any suggestions/direction would be greatly appreciated. Thanks.
Here is the code that I'm working with:
public void connect() {
LOGGER.info("Connecting ... ");
while (!shouldTerminate) {
ActiveSocket activeSocket = null;
Socket newSocket = null;
int tries = 0;
int loopCounter = 0;
if (isServer) {
if (host == null) {
LOGGER.info("Must specify a host ip or host name with HOST configuration tag ");
return;
} else {
// keep accepting new socket connections until you have max active sockets
while (!shouldTerminate && (activeSockets.size() < this.maxActiveSockets)) {
activeSocket = new ActiveSocket();
newSocket = null;
if (serverSocket != null) {
try {
LOGGER.info("Accept socket ");
String ipAddrValue = serverSocket.getInetAddress().toString();
String hostValue = host;
int portValue = serverSocket.getLocalPort();
**newSocket = serverSocket.accept();**
} catch (final IOException ex) {
if (shouldTerminate) {
if (ex.getMessage() != null) {
LOGGER.info(ex.getMessage());
}
} else {
LOGGER.info("IOException while accepting connection ");
LOGGER.warn(FormatData.fullStackTrace(ex));
}
newSocket = null;
}
if (newSocket != null) {
try {
LOGGER.info("Socket keepalive ... ");
newSocket.setKeepAlive(true);
activeSocket.setSocket(newSocket);
increaseConnects();
} catch (final SocketException ex) {
LOGGER.info("SocketException while opening socket ");
LOGGER.warn(FormatData.fullStackTrace(ex));
newSocket = null;
}
}
} else { // first time through the loop
try {
LOGGER.info("Opening server socket (" + host + "," + port + ") for BankID:" + Integer.toString(this.getBankID()));
serverSocket = new ServerSocket(port);
} catch (final IOException ex) {
LOGGER.info("Unable to open server socket socket (" + host + "," + port + ")");
if (ex.getMessage().indexOf("Cannot assign requested address") > -1) {
this.terminate();
final String logMessage = "Invalid IP Address assigned:" + host + ",port:" + port;
final String subject = logMessage;
ATMServer.sendNotification(subject, logMessage);
} else if (tries == 0) {
tries++;
final String logMessage = "Unable to open server socket (" + host + "," + port + ")";
final String subject = "Unable to open server socket (" + host + "," + port + ")";
ATMServer.sendNotification(subject, logMessage);
}
LOGGER.warn(FormatData.fullStackTrace(ex));
}
}
}
}
} else { // client socket -- connecting to a bank
LOGGER.info("Not server and terminal type is null ");
while (!shouldTerminate && (activeSockets.size() < this.maxActiveSockets)) {
activeSocket = new ActiveSocket();
newSocket = null;
if (this.isInForcedStandIn()) {
LOGGER.info("Forced standin " + getName());
try {
Thread.sleep(3000); // #TODO switch to a
// notification when not in
// standin
} catch (final InterruptedException ex) {
LOGGER.info("Interrupted while waiting for connection ");
LOGGER.warn(FormatData.fullStackTrace(ex));
}
} else {
if (!shouldTerminate) {
if ((loopCounter % 120) == 0) {
try {
LOGGER.info("Connecting to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
newSocket = new Socket(InetAddress.getByName(remoteHost), remotePort);
if (newSocket.isConnected()) {
tries = 0;
LOGGER.info("socket connected to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
}
newSocket.setKeepAlive(true);
if (newSocket.getKeepAlive()) {
LOGGER.info("socket keep alive to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
}
activeSocket.setSocket(newSocket);
increaseConnects();
} catch (final IOException ex) {
loopCounter++;
tries++;
LOGGER.info("SocketException while opening remote socket (" + remoteHost + "," + remotePort + ") " + " " + ex.getClass() + " " + ex.getMessage());
if ((tries % 300) == 0) {
recordErrorToDatabase(ex.getMessage());
}
}
} else {
loopCounter++;
try {
synchronized (clientConnectLock) {
clientConnectLock.wait(1000);
}
} catch (final InterruptedException inex) {
LOGGER.info("SocketException while opening remote socket " + Thread.currentThread().getName());
LOGGER.warn(FormatData.fullStackTrace(inex));
if (!this.shouldTerminate) {
recordErrorToDatabase("InterruptedException without terminate set.");
}
}
}
}
}
}
}
try {
// here, if we created a new ActiveSocket, establish dataInput and dataOuput streams
// then add to the list of active streams.
// for Discover, this will mean adding up to MaxActiveSockets # of sockets
// to the activeSockets list.
// for each other SwitchChannel, this will be the only activeSocket
if (activeSocket != null) {
LOGGER.info("Creating serverIn/serverOut data streams " + Thread.currentThread().getName());
DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(newSocket.getInputStream()));
if (newSocket.isConnected()) {
LOGGER.info("socket still connected to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
}
DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(newSocket.getOutputStream(), 2048));
activeSocket.setDataInputStream(dataInputStream);
activeSocket.setDataOutputStream(dataOutputStream);
activeSockets.add(activeSocket);
activeSocket.setNumReceivers(this.numReceivers);
ReceiveQueuer[] receiveQueuers = activeSocket.getReceiveQueuers();
LOGGER.info("Starting receive queuers");
for (int cnt = 0; cnt < numReceivers; cnt++) {
receiveQueuers[cnt].setName(this.systemName + "-Socket-" + Integer.toString(activeSockets.size()) + "-ReceiveQueuer-" + Integer.toString(cnt));
receiveQueuers[cnt].setActiveSocket(activeSocket);
receiveQueuers[cnt].start();
}
}
} catch (final Exception ex) {
LOGGER.info("Exception while creating input/output streams " + Thread.currentThread().getName());
LOGGER.warn(FormatData.fullStackTrace(ex));
}
}
if (!shouldTerminate) {
LOGGER.info("Socket connection complete " + Thread.currentThread().getName());
} else {
LOGGER.info("Stopped establishing socket connection " + Thread.currentThread().getName());
}

Parsing data read from multiple sensors on Arduino

So here is the code we're implementing for our Java GUI. The problem is, since the serial data is read in bits, we can't seem to come up with a way to separate the data from three different sensors (three LM35 temperature sensors as placeholders). The problem lies in the serialevent class.
import gnu.io.*;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Scanner;
import java.util.TooManyListenersException;
public class Communicator implements SerialPortEventListener
{
//Passed from main GUI.
GUI window = null;
//For containing the ports that will be found.
private Enumeration ports = null;
//map the port names to CommPortIdentifiers
private HashMap portMap = new HashMap();
//This is the object that contains the opened port.
private CommPortIdentifier selectedPortIdentifier = null;
private SerialPort serialPort = null;
//Input and output streams for sending and receiving data.
private InputStream input = null;
private OutputStream output = null;
//Just a boolean flag that I use for enabling
//and disabling buttons depending on whether the program
//is connected to a serial port or not.
private boolean bConnected = false;
//The timeout value for connecting with the port.
final static int TIMEOUT = 2000;
//Some ASCII values for for certain things.
final static int SPACE_ASCII = 32;
final static int DASH_ASCII = 45;
final static int NEW_LINE_ASCII = 10;
//A string for recording what goes on in the program;
//this string is written to the GUI.
String logText = "";
public Communicator(GUI window)
{
this.window = window;
}
//Search for all the serial ports
// Pre: none
// Post: adds all the found ports to a combo box on the GUI
public void searchForPorts()
{
ports = CommPortIdentifier.getPortIdentifiers();
while (ports.hasMoreElements())
{
CommPortIdentifier curPort = (CommPortIdentifier)ports.nextElement();
//Get only serial ports
if (curPort.getPortType() == CommPortIdentifier.PORT_SERIAL)
{
window.cboxPorts.addItem(curPort.getName());
portMap.put(curPort.getName(), curPort);
}
}
}
//Connect to the selected port in the combo box
// Pre : ports are already found by using the searchForPorts method
// Post: the connected communications port is stored in commPort, otherwise,
// an exception is generated
public void connect()
{
String selectedPort = (String)window.cboxPorts.getSelectedItem();
selectedPortIdentifier = (CommPortIdentifier)portMap.get(selectedPort);
CommPort commPort = null;
try
{
//The method below returns an object of type CommPort
commPort = selectedPortIdentifier.open("TigerControlPanel", TIMEOUT);
//The CommPort object can be casted to a SerialPort object
serialPort = (SerialPort)commPort;
//For controlling GUI elements
setConnected(true);
//Logging
logText = selectedPort + " opened successfully.";
window.txtLog.setForeground(Color.black);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.black);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.black);
window.txtLog2.append(logText + "\n");
//CODE ON SETTING BAUD RATE, ETC. OMITTED
//XBEE PAIR IS ASSUMED TO HAVE THE SAME SETTINGS ALREADY
//Enables the controls on the GUI if a successful connection is made
window.keybindingController.toggleControls();
}
catch (PortInUseException e)
{
logText = selectedPort + " is in use. (" + e.toString() + ")";
window.txtLog.setForeground(Color.RED);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.RED);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.RED);
window.txtLog2.append(logText + "\n");
}
catch (Exception e)
{
logText = "Failed to open " + selectedPort + "(" + e.toString() + ")";
window.txtLog.append(logText + "\n");
window.txtLog.setForeground(Color.RED);
window.txtLog1.append(logText + "\n");
window.txtLog1.setForeground(Color.RED);
window.txtLog2.append(logText + "\n");
window.txtLog2.setForeground(Color.RED);
}
}
//Open the input and output streams
// pre: an open port
// post: initialized intput and output streams for use to communicate data
public boolean initIOStream()
{
//Return value for whather opening the streams is successful or not
boolean successful = false;
try {
input = serialPort.getInputStream();
output = serialPort.getOutputStream();
successful = true;
return successful;
}
catch (IOException e) {
logText = "I/O Streams failed to open. (" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.red);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.red);
window.txtLog2.append(logText + "\n");
return successful;
}
}
//Starts the event listener that knows whenever data is available to be read
// pre: an open serial port
// post: an event listener for the serial port that knows when data is recieved
public void initListener()
{
try
{
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
}
catch (TooManyListenersException e)
{
logText = "Too many listeners. (" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.red);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.red);
window.txtLog2.append(logText + "\n");
}
}
//Disconnect the serial port
// pre : an open serial port
// post: clsoed serial port
public void disconnect()
{
//Close the serial port
try
{
serialPort.removeEventListener();
serialPort.close();
input.close();
output.close();
setConnected(false);
window.keybindingController.toggleControls();
logText = "Disconnected.";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.red);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.red);
window.txtLog2.append(logText + "\n");
}
catch (Exception e)
{
logText = "Failed to close " + serialPort.getName() + "(" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.red);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.red);
window.txtLog2.append(logText + "\n");
}
}
final public boolean getConnected()
{
return bConnected;
}
public void setConnected(boolean bConnected)
{
this.bConnected = bConnected;
}
//What happens when data is received
// pre : serial event is triggered
// post: processing on the data it reads
public void serialEvent(SerialPortEvent evt) {
if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE)
{
try
{
byte singleData = (byte)input.read();
//byte[] buffer = new byte[128];
if (singleData != NEW_LINE_ASCII)
{
logText = new String(new byte[] {singleData});
window.txtLog.append(logText);
}
else
{
window.txtLog.append("\n");
}
}
catch (Exception e)
{
logText = "Failed to read data. (" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
}
}
}
//Method that can be called to send data
// pre : open serial port
// post: data sent to the other device
}
If the Arduino is simply sending the temperature back as a string from each sensor in sequence (I assume it is but you haven't specified what it's sending at all, so I could be wrong) then assuming you haven't disabled reset on serial connect, you could simply take note of the order the temperatures come in at - say the first temperature read is from sensor 1, the second from sensor 2, the third from sensor 3, the fourth from sensor 1, and so on.
However, for a clearer and more reliable way I'd recommend modifying the Arduino code to send back details of what sensor each reading came from rather than just sending back the raw bits - changing the code in this way should be relatively trivial from the Arduino's side, then makes parsing the data PC side much easier.

Issue creating number of sockets one by one in loop

I have made a school app in which teacher sends a string message to the students. Teacher holds a hash-map of logged in students. When Teacher presses next page command in his tablet, students should see the next page. And that is what happens normally, but sometimes when teacher is not able to make connection with a single student in the hash-map for some reason whole process gets very slow and rarely the systems ceases to respond any further.
public static void SendToEveryStudent(String message) throws IOException, ELearningException
{
String command;
String host;
int port;
String failedStudents = "";
int leftOverStudents = 0;
ApplicationLog.log("Command Queue: sendToEveryStudent : " + message, InitializeTeacherJar.getInstance().isLoggingEnabled());
int socketTimeout;
Socket studentSocket = null;
StudentUtility.studentCounter = 0;
port = InitializeTeacherJar.getGlobalPort();
socketTimeout = InitializeTeacherJar.getInstance().getTeacherStudentSocketTimeout();
// Check if no of students are more then zero
if (InitializeTeacherJar.getInstance().getStudentIPList().keySet().size() > 0)
{
StudentUtility.studentCounter = InitializeTeacherJar.getInstance().getStudentIPList().keySet().size();
for (String key : InitializeTeacherJar.getInstance().getStudentIPList().keySet())
{
try
{
host = InitializeTeacherJar.getInstance().getStudentIPList().get(key).get(0);
if (!host.equalsIgnoreCase(""))
{
if (studentSocket != null)
{
studentSocket.close();
studentSocket = null;
}
try
{
studentSocket = new Socket(InetAddress.getByName(host), port);
studentSocket.setSoTimeout(socketTimeout);
}
catch (Exception e)
{
leftOverStudents++;
failedStudents = key + InitializeTeacherJar.getInstance().getDelimiter();
ApplicationLog.log("Exception :: " + host +" is not reachable as the server is down at his end.", InitializeTeacherJar.getInstance().isLoggingEnabled());
continue;
}
if (studentSocket != null)
{
if (InitializeTeacherJar.getInstance().getStudentIPList().get(key).get(1).equalsIgnoreCase("present"))
{
studentSocket.getOutputStream().write((message + "\n").getBytes());
ApplicationLog.log("Command Queue: Message to student :: " + message + " :: " + key, InitializeTeacherJar.getInstance().isLoggingEnabled());
BufferedReader in = new BufferedReader(new InputStreamReader(studentSocket.getInputStream()));
String line = null;
while ((line = in.readLine()) != null)
{
if (line.equalsIgnoreCase("ack"))
{
//ApplicationLog.log("InitializeTeacherJar :: Student Counter is :: " + StudentUtility.studentCounter, InitializeTeacherJar.getInstance().isLoggingEnabled());
ApplicationLog.log("Command Queue: Ack recvd for :: "+ key + " :: " + host, InitializeTeacherJar.getInstance().isLoggingEnabled());
}
else
{
ApplicationLog.log("Command Queue: Did Not received ACK for :: "+ key + " :: " + host, InitializeTeacherJar.getInstance().isLoggingEnabled());
}
}
}
else
{
studentSocket.getOutputStream().write((CONSTANTS.ALERT + InitializeTeacherJar.getInstance().getDelimiter() + ErrorCodes.TABLET_NOT_ASSIGNED).getBytes());
ApplicationLog.log("StudentUtility :: Tablet not assigned to :: " + key, InitializeTeacherJar.getInstance().isLoggingEnabled());
}
studentSocket.close();
}
}
}
catch (Exception e)
{
ApplicationLog.log("CommandQueue :: sendToEveryStudent Exception :: " + e, InitializeTeacherJar.getInstance().isLoggingEnabled());
studentSocket.close();
}
studentSocket = null;
}
}
if (leftOverStudents > 0)
{
failedStudents = StudentUtility.m_stripLastChar(failedStudents);
ApplicationLog.log("SendToEveryStudent :: Some Students Were Not Connected :: " + ErrorCodes.TEACHER_STUDENT_SOCKET_NOT_CONNECTED + InitializeTeacherJar.getInstance().getDelimiter() + failedStudents, InitializeTeacherJar.getInstance().isLoggingEnabled());
InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().write((CONSTANTS.ALERT + InitializeTeacherJar.getInstance().getDelimiter() + ErrorCodes.TEACHER_STUDENT_SOCKET_NOT_CONNECTED + InitializeTeacherJar.getInstance().getDelimiter() + failedStudents + InitializeTeacherJar.getInstance().getCommandDelimeter()).getBytes());
InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().flush();
}
else if (leftOverStudents == 0)
{
InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().write((CONSTANTS.ALERT + InitializeTeacherJar.getInstance().getDelimiter() + CONSTANTS.SENT_SUCCESSFULLY_TO_ALL + InitializeTeacherJar.getInstance().getDelimiter() + "Sent To All" + InitializeTeacherJar.getInstance().getCommandDelimeter()).getBytes());
InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().flush();
}
StudentUtility.studentCounter = StudentUtility.studentCounter - leftOverStudents;
}
}
The area where my apprehensions lies are
1) Loop - loop, which makes the sockets and call the blocking call i.e. accept, should go in a AsynTask.
2) SocketTimeout - it should be bare minimal, right now its 1.2 secs. What is the optimal value for this?
This might be little too much code, but I hope the explanation helps.
Thanking in advance.
This is sort of a backwards setup. Imagine a web server that would go and connect to all potential clients to push a web page - skipping all the NAT/firewall issues that just doesn't scale and is prone to head-of-the-list delays in a sequential single-threaded implementation and to waste of resources in any multi-threaded setup.
I would suggest switching to conventional client-server model where teacher is the server, and students are the clients connecting on demand.
For the time being I have got a shim to be over with it. However I am going to try the "collection of live sockets" thing after I get over with the due release of the software.
Anyways what i have done is following changes to the above code:
try
{
inAddress = InetAddress.getByName(host);
if (!inAddress.isReachable())
{
leftOverStudents++;
failedStudents = key + InitializeTeacherJar.getInstance().getDelimiter();
ApplicationLog.log("Exception :: " + host +" is not reachable as the server is down at his end.", InitializeTeacherJar.getInstance().isLoggingEnabled());
continue;
}
studentSocket = new Socket(inAddress, port);
studentSocket.setSoTimeout(socketTimeout);
}
All I do is just move to next student if it is not reachable.
Thanks for the help anyways.

Categories