I am working on a socket server/ client in java. The client sends a request to ask for time. The server sends a response. The synchronized client time is calculating using Cristian’s Algorithm. Tclient = Tserver + (T1 - T0)/2
Server code:
#Override
public void run() {
String received;
while (true) {
try {
// Ask user what he wants
dos.writeUTF("Type 't' to get time..\n" +
"Type exit to terminate connection.");
// receive the answer from client
received = dis.readUTF();
if (received.equals("exit")) {
System.out.println("Client " + this.s + " sends exit...");
System.out.println("Closing this connection.");
this.s.close();
System.out.println("Connection closed");
break;
} else if (received.equals("t")) {
long currentTimeMillis = Instant.now().toEpochMilli();
dos.writeLong(currentTimeMillis);
String ip=(((InetSocketAddress) s.getRemoteSocketAddress()).getAddress()).toString().replace("/","");
insert(ip, currentTimeMillis);
} else {
dos.writeUTF("Invalid input");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client code:
try (Scanner scn = new Scanner(System.in);
Socket s = new Socket(InetAddress.getByName("localhost"), 5068);
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream())) {
// the following loop performs the exchange of
// information between client and client handler
while (true) {
System.out.println(dis.readUTF());
String tosend = scn.nextLine();
dos.writeUTF(tosend);
//Time when the request is sent
Instant requestTimeInstant = Instant.now();
System.out.println("Time at which the request is sent " + getFormattedTime(requestTimeInstant.toEpochMilli()));
// If client sends exit,close this connection
// and then break from the while loop
if (tosend.equals("exit")) {
System.out.println("Closing this connection : " + s);
s.close();
System.out.println("Connection closed");
break;
} else if(tosend.equals("t")){
// printing date or time as requested by client
long serverTime = dis.readLong();
Instant responseTimeInstant = Instant.now();
System.out.println("Time at which the response is received Instant " + getFormattedTime(responseTimeInstant.toEpochMilli()));
//Apply christian' algorithm Tclient = Tserver + (T1 - T0)/2 where
// T0 time at which the request is sent
//and T1 time at which the response is received
long deltaMill = Duration.between(requestTimeInstant,responseTimeInstant).toMillis();
long halfDeltaTime = deltaMill / 2;
System.out.println(deltaMill);
System.out.println("Added time to serverTime " + halfDeltaTime + " Milliseconds");
long clientTimeMills = serverTime + halfDeltaTime;
System.out.println("Server time " + getFormattedTime(serverTime));
System.out.println("client time " + getFormattedTime(clientTimeMills));
System.out.println("Sync time error " +(responseTimeInstant.toEpochMilli() -clientTimeMills) + " Milliseconds");
}
}
} catch (Exception e) {
e.printStackTrace();
}
I am actually having an incoherent output (only in the first response for the request, there is a sync time error) and I can not figure out the reason:
Related
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);
}
I have an error when a client closes the connection from the socket. What is supposed to happen is that the user closes their client, the server then receives this and should decrement the users who are connected which is stored in a relative integer value. However I receive an error relating to the for loop on the remove a user function.
public synchronized void removeUsers(Socket client,int clientUser)
{
int index=0;
for (ClientHandler newHandler:userList)
{
if(newHandler.getUserId() == clientUser)
{
try
{
client.close();
Thread.currentThread().isInterrupted();
userList.remove(index);
}
catch (IOException e)
{
System.out.println("Unable to disconnect!");
System.exit(1);
}
}
index++;
}
}
Client handler run:
public void run()
{
String message;
message = input.nextLine(); //Note method!
getMessage(message);
System.out.println(message.substring(0, count+1)+"-"+message.substring(count+1));
while (!message.substring(0, count+1).equals("***CLOSE***"))
{
if(message.equals(user.getItemName(1)+"$status$")|| //checks for status of Ball
message.equals(user.getItemName(2)+"$status$"))
{
if (user.BidItem(user.getItemName(1)))
{
System.out.println("Top bid for " + //posts for server
message.substring(0, count+1) + " is: "
+ user.getTopBid(message.substring(0, count+1)));
output.println("Top bid for " + //posts for client
message.substring(0, count+1) + " is: "
+ user.getTopBid(message.substring(0, count+1))
+ " by User" +
user.getTopBidder(message.substring(0, count+1)));
}
else
{
System.out.println("-1");
output.println("-1");
}
}
else
{
if(user.BidItem(message.substring(count+2))) //same but now for Plate
{
if(user.isGrtrThanTopBid(message.substring(count+2),
Double.parseDouble(message.substring(0, count+1))))
{
user.setTopBid(message.substring(count+2),
Double.parseDouble(message.substring(0, count+1)), clientUser);
System.out.println("Bid Accepted for " + message.substring(count+2));
output.println("Bid Accepted for " + message.substring(count+2));
}
else
{
System.out.println("Low bid for " + message.substring(count+2));
output.println("Low bid for " + message.substring(count+2));
}
}
else
{
System.out.println("Late bid for " + message.substring(count+2));
output.println("Late bid for " + message.substring(count+2));
}
}
message = input.nextLine();
count = 0;
getMessage(message);
}
output.println(" messages received.");
System.out.println("\n* Closing connection... *");
user.removeUsers(client,clientUser);
}
The full error is here:
Exception in thread "Thread-2" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at Users.removeUsers(AuctionServer.java:211) //Relates to top of for loop
at ClientHandler.run(AuctionServer.java:435)
You can't remove objects from lists when you iterates on them.
Try this.
Instead use a queue.
Queue queue = new LinkedList<Client>();
int index=0;
for (ClientHandler newHandler:userList)
{
if(newHandler.getUserId() == clientUser)
{
try
{
client.close();
Thread.currentThread().isInterrupted();
queue.add(userList.get(index));
}
catch (IOException e)
{
System.out.println("Unable to disconnect!");
System.exit(1);
}
}
index++;
}
while(!queue.isEmpty()) {
userList.remove(queue.remove());
}
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.)
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());
}
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.