Data not synchornizing java sockets - java

I am writing a auction server and client and using a class called BidHandler to deal with the bids another class AuctionItem to deal with the items for auction. The main problem I am having is little synchroization problem.
Screen output of client server
as can see from the image at 1st it takes the new bid and changes the value of the time to it, but when one the user enters 1.0 the item seems to be changed to that. But later on when the bid changes again to 15.0 it seems to stay at that price. Is there any reason for that. I have included my code below. Sorry if didnt explain this well.
This is the auction client
import java.io.*;
import java.net.*;
public class AuctionClient
{
private AuctionGui gui;
private Socket socket;
private DataInputStream dataIn;
private DataOutputStream dataOut;
//Auction Client constructor String name used as identifier for each client to allow server to pick the winning bidder
public AuctionClient(String name,String server, int port)
{
gui = new AuctionGui("Bidomatic 5000");
gui.input.addKeyListener (new EnterListener(this,gui));
gui.addWindowListener(new ExitListener(this));
try
{
socket = new Socket(server, port);
dataIn = new DataInputStream(socket.getInputStream());
dataOut = new DataOutputStream(socket.getOutputStream());
dataOut.writeUTF(name);
while (true)
{
gui.output.append("\n"+dataIn.readUTF());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void sentBid(String bid)
{
try
{
dataOut.writeUTF(bid);
}
catch(IOException e)
{
e.printStackTrace();
}
}
public void disconnect()
{
try
{
socket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void main (String args[]) throws IOException
{
if(args.length!=3)
{
throw new RuntimeException ("Syntax: java AuctionClient <name> <serverhost> <port>");
}
int port = Integer.parseInt(args[2]);
AuctionClient a = new AuctionClient(args[0],args[1],port);
}
}
The Auction Server
import java.io.*;
import java.net.*;
import java.util.*;
public class AuctionServer
{
public AuctionServer(int port) throws IOException
{
ServerSocket server = new ServerSocket(port);
while(true)
{
Socket client = server.accept();
DataInputStream in = new DataInputStream(client.getInputStream());
String name = in.readUTF();
System.out.println("New client "+name+" from " +client.getInetAddress());
BidHandler b = new BidHandler (name, client);
b.start();
}
}
public static void main(String args[]) throws IOException
{
if(args.length != 1)
throw new RuntimeException("Syntax: java AuctionServer <port>");
new AuctionServer(Integer.parseInt(args[0]));
}
}
The BidHandler
import java.net.*;
import java.io.*;
import java.util.*;
import java.lang.Float;
public class BidHandler extends Thread
{
Socket socket;
DataInputStream in;
DataOutputStream out;
String name;
float currentBid = 0.0f;
AuctionItem paper = new AuctionItem(" News Paper ", " Free newspaper from 1990 ", 1.0f, false);
protected static Vector handlers = new Vector();
public BidHandler(String name, Socket socket) throws IOException
{
this.name = name;
this.socket = socket;
in = new DataInputStream (new BufferedInputStream (socket.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
}
public synchronized void run()
{
try
{
broadcast("New bidder has entered the room");
handlers.addElement(this);
while(true)
{
broadcast(paper.getName() + paper.getDescription()+" for sale at: " +paper.getPrice());
while(paper.getStatus() == false)
{
String message = in.readUTF();
currentBid = Float.parseFloat(message);
broadcast("Bidder entered " +currentBid);
if(currentBid > paper.getPrice())
{
paper.setPrice(currentBid);
broadcast("New Higgest Bid is "+paper.getPrice());
}
else if(currentBid < paper.getPrice())
{
broadcast("Higgest Bid is "+paper.getPrice());
}
else if(currentBid == paper.getPrice())
{
broadcast("Higgest Bid is "+paper.getPrice());
}
}
}
}
catch(IOException ex)
{
System.out.println("-- Connection to user lost.");
}
finally
{
handlers.removeElement(this);
broadcast(name+" left");
try
{
socket.close();
}
catch(IOException ex)
{
System.out.println("-- Socket to user already closed ?");
}
}
}
protected static void broadcast (String message)
{
synchronized(handlers)
{
Enumeration e = handlers.elements();
while(e.hasMoreElements())
{
BidHandler handler = (BidHandler) e.nextElement();
try
{
handler.out.writeUTF(message);
handler.out.flush();
}
catch(IOException ex)
{
handler = null;
}
}
}
}
}
The AuctionItem Class
class AuctionItem
{
String itemName;
String itemDescription;
float itemPrice;
boolean itemStatus;
//Create a new auction item with name, description, price and status
public AuctionItem(String name, String description, float price, boolean status)
{
itemName = name;
itemDescription = description;
itemPrice = price;
itemStatus = status;
}
//return the price of the item.
public synchronized float getPrice()
{
return itemPrice;
}
//Set the price of the item.
public synchronized void setPrice(float newPrice)
{
itemPrice = newPrice;
}
//Get the status of the item
public synchronized boolean getStatus()
{
return itemStatus;
}
//Set the status of the item
public synchronized void setStatus(boolean newStatus)
{
itemStatus = newStatus;
}
//Get the name of the item
public String getName()
{
return itemName;
}
//Get the description of the item
public String getDescription()
{
return itemDescription;
}
}
There is also simple GUI to go with this that seems to be working fine. If anyone wants it will include the GUI code.

Your methods AuctionItem.getPrice and AuctionItem.setPrice are synchronized, but it's really not sufficient here.
In BitHandler.run you often have some if that checks the price and then you change the price. You need to synchronize these two operations together since another thread could change the price between those two operations.
For example, if two thread try to set the new highest bid to 12.0 and 15.0, they will both determine that they are higher than 1.0 and they'll both set the price, put you might end up with setPrice(15.0) followed by setPrice(12.0), which leaves the high bid at 12.0.
You either can use an explicit lock to synchronize a series of operations on the price, or you can define a new synchronized method changePriceIfHigherThanHighest(float newPrice).
You might have other synchronization bugs; I didn't check thoroughly.

Related

Java: can't close Client connection without closing Server

I made a previous post a bit back working on getting a two-way server/client socket connection working. I've largely succeeded yet, but I still have one more step as a barrier. I'd like to make it so the client disconnects after they perform an operation, but the server remains up and can take in another client operation until the client makes a specific response. I'm attempting to do this through while loops in both the client and server. This is my server class:
import java.net.*;
import java.io.*;
public class ServerDemo {
private Socket mySocket = null;
private ServerSocket server = null;
private static ObjectInputStream in=null;
private static ObjectOutputStream out=null;
private static Payload myPayload=new Payload();
public ServerDemo(int port) throws ClassNotFoundException
{
double time=0;
int bytes=0;
try
{
server = new ServerSocket(port);
System.out.println("Server started");
System.out.println("Waiting for a client ...");
}
catch(IOException i)
{
System.out.println(i);
myPayload.setRepeat(false);
}
try {
while(myPayload.getRepeat()==true) {
mySocket = server.accept();
System.out.println("Client accepted");
in = new ObjectInputStream(
new BufferedInputStream(mySocket.getInputStream()));
out = new ObjectOutputStream(mySocket.getOutputStream());
myPayload.setDataPasses(10);
while (myPayload.getCurr()<myPayload.getDataPasses())
{
try
{
myPayload= (Payload) in.readObject();
myPayload.raisePasses();
out.writeObject(myPayload);
}
catch(IOException i)
{
System.out.println(i);
myPayload.setRepeat(false);
}
}
System.out.println("Closing connection");
mySocket.close();
in.close();
System.out.println("Operation Complete");
System.out.println("Client Address: "+myPayload.getClient());
System.out.println("Server Address: "+myPayload.getServer());
time=System.nanoTime()-(myPayload.getTime());
time=time/1000000000;
System.out.println("Total Time (in seconds): "+time);
bytes=(int) ( ((myPayload.getPacket().length)*myPayload.getDataPasses())/time);
System.out.println("Bytes per Second: "+bytes);
}
}
catch(IOException i)
{
System.out.println(i);
myPayload.setRepeat(false);
}
}
public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub
ServerDemo server=new ServerDemo(5000);
}
}
This is my client class:
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class ClientDemo {
private Socket mySocket = null;
private ObjectInputStream in= null;
private ObjectOutputStream out = null;
private static long roundTrips=1;
private static Payload myPayload=new Payload();
public ClientDemo(String address, int port) throws ClassNotFoundException
{
int packageSize=1;
double time=0;
int bytes=0;
try
{
mySocket = new Socket(address, port);
System.out.println("Connected");
out = new ObjectOutputStream(mySocket.getOutputStream());
in = new ObjectInputStream(new BufferedInputStream(mySocket.getInputStream()));
}
catch(UnknownHostException u)
{
System.out.println(u);
}
catch(IOException i)
{
System.out.println(i);
}
while (myPayload.getCurr()<myPayload.getDataPasses())
{
try
{
if(myPayload.getCurr()==0) {
myPayload.setTime(System.nanoTime());
}
out.writeObject(myPayload);
myPayload= (Payload) in.readObject();
}
catch(IOException i)
{
System.out.println(i);
}
}
try
{
in.close();
out.close();
mySocket.close();
System.out.println("Operation Complete");
System.out.println("Client Address: "+myPayload.getClient());
System.out.println("Server Address: "+myPayload.getServer());
time=System.nanoTime()-(myPayload.getTime());
time=time/1000000000;
System.out.println("Total Time (in seconds): "+time);
bytes=(int) ( ((myPayload.getPacket().length)*myPayload.getDataPasses())/time);
System.out.println("Bytes per Second: "+bytes);
System.out.println("");
}
catch(IOException i)
{
System.out.println(i);
}
}
public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub
boolean isValid=false;
String response="";
int size=16384;
Scanner myScanner = new Scanner(System.in);
ClientDemo client=null;
String server="";
while (size>-1) {
System.out.println("Please enter a max data packet size. Enter -1 to end the program");
while(isValid==false) {
response=myScanner.next();
if(Long.parseLong(response)>=-1 && Long.parseLong(response)<=16384) {
isValid=true;
size=Integer.parseInt(response);
if(size>-1) {
myPayload.setPacket(fillPacket(size));
}
}
else {
System.out.println("Invalid Response. Please enter a value between 1 and 16384.");
}
}
if(size==-1) {
System.out.println("Closing server...");
myPayload.setRepeat(false);
client= new ClientDemo(server, 5000);
}
else {
isValid=false;
System.out.println("Please enter an amount of data passes.");
while(isValid==false) {
response=myScanner.next();
if(Long.parseLong(response)>=1) {
isValid=true;
roundTrips=Long.parseLong(response);
myPayload.setDataPasses(roundTrips);
}
else {
System.out.println("Invalid Response. Please enter a value of 1 or greater.");
}
}
isValid=false;
System.out.println("Please enter your client address.");
response=myScanner.next();
myPayload.setClient(response);
System.out.println("Please enter a server to connect to.");
response=myScanner.next();
server=response;
myPayload.setServer(server);
myPayload.reset();
client= new ClientDemo(server, 5000);
}
}
}
public static int[] fillPacket(int size) {
int[] thePacket= new int[size];
int current=0;
while(current<size) {
for(int counter=0;counter<100;counter++) {
if(current<size) {
thePacket[current]=counter;
current++;
}
}
}
return thePacket;
}
}
When I attempt to run both, the operation I have set up works completely fine, and entering -1 to close the program works but I run into errors when performing operations beyond that. Attempting to set size to -1 to end the program at this point causes an endless loop of
java.io.EOFException
inside ServerDemo, while entering what should be a valid packet size between 0 and 16384 instead produces an endless stream of
java.net.SocketException: Broken pipe (Write failed)
inside ClientDemo. Perhaps most strangely, the latter error only SOMETIMES occurs, not always. If anyone has any pointers on how to get this correctly working and remedying these errors, I would greatly appreciate it!
I would rather change approach. The usual one when doing this kind of stuff is create a thread to listen on your port, then, when a client connects, immediately dispatch the new task to a thread pool and continue listening.
This way not only your server will continue listening after the client disconnects, but also will be able to serve multiple clients in parallel (up to the thread pool size).
Also please use try-with-resources whenever possible to easily avoid resource leaking.
So your code could be changed to something like this:
Server class
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ServerDemo {
private int port;
private Thread listenThread;
private ExecutorService serverPool;
public ServerDemo(int port) {
this.port = port;
}
public synchronized void startServer() {
serverPool = Executors.newFixedThreadPool(4);
listenThread = new Thread(() -> {
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println(String.format("Listening on port %d", port));
System.out.println("1");
while (!Thread.interrupted()) {
System.out.println("2");
Socket clientSocket = serverSocket.accept();
System.out.println("3");
if(!Thread.currentThread().isInterrupted())
serverPool.submit(new ClientTask(clientSocket));
System.out.println("4");
}
} catch (IOException e) {
System.err.println("Error processing client connection");
e.printStackTrace();
}
System.out.println("ListenThread stopped");
}, "ListenThread");
listenThread.start();
}
public synchronized void stopServer() {
System.out.println("Stopping server...");
if (serverPool != null) {
serverPool.shutdown();
serverPool = null;
}
if(listenThread != null) {
listenThread.interrupt();
try (Socket voidSocket = new Socket("localhost", port)) {
// Void socket to unlock the accept() call
} catch (IOException e) {
}
listenThread = null;
}
}
private class ClientTask implements Runnable {
private final Socket clientSocket;
private ClientTask(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
System.out.println("Client accepted");
Payload myPayload = new Payload();
try (ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(clientSocket.getInputStream()));
ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream())) {
myPayload.setDataPasses(10);
while (myPayload.getCurr() < myPayload.getDataPasses()) {
try {
myPayload = (Payload) in.readObject();
myPayload.raisePasses();
out.writeObject(myPayload);
} catch (IOException i) {
System.out.println(i);
break;
} catch (ClassNotFoundException e) {
System.err.println("Error finding class to deserialize");
e.printStackTrace();
}
}
System.out.println("Operation Complete");
System.out.println("Client Address: " + myPayload.getClient());
System.out.println("Server Address: " + myPayload.getServer());
double time = System.nanoTime() - (myPayload.getTime());
time = time / 1000000000;
System.out.println("Total Time (in seconds): " + time);
int bytes = (int) (((myPayload.getPacket().length) * myPayload.getDataPasses()) / time);
System.out.println("Bytes per Second: " + bytes);
} catch (IOException e1) {
System.err.println("Error opening client I/O streams");
e1.printStackTrace();
}
try {
System.out.println("Closing connection");
clientSocket.close();
} catch (IOException e) {
System.err.println("Error closing client connection");
e.printStackTrace();
}
if(!myPayload.getRepeat())
stopServer();
}
}
public static void main(String[] args) throws ClassNotFoundException {
ServerDemo server = new ServerDemo(5000);
server.startServer();
// do other stuff including trapping for sigterm, then call server.stopServer() if needed
}
}
Client class
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class ClientDemo {
private static void executeClientJob(Payload myPayload, int port) {
double time = 0;
int bytes = 0;
try (Socket mySocket = new Socket(myPayload.getServer(), port);
ObjectOutputStream out = new ObjectOutputStream(mySocket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(mySocket.getInputStream()))) {
System.out.println("Connected");
while (myPayload.getCurr() < myPayload.getDataPasses()) {
if (myPayload.getCurr() == 0)
myPayload.setTime(System.nanoTime());
out.writeObject(myPayload);
myPayload = (Payload) in.readObject();
}
System.out.println("Operation Complete");
System.out.println("Client Address: " + myPayload.getClient());
System.out.println("Server Address: " + myPayload.getServer());
time = System.nanoTime() - (myPayload.getTime());
time = time / 1000000000;
System.out.println("Total Time (in seconds): " + time);
bytes = (int) (((myPayload.getPacket().length) * myPayload.getDataPasses()) / time);
System.out.println("Bytes per Second: " + bytes);
System.out.println("");
} catch (UnknownHostException u) {
u.printStackTrace();
} catch (IOException i) {
i.printStackTrace();
} catch (ClassNotFoundException c) {
c.printStackTrace();
}
}
private static void testAutomatic() {
for (int i = 0; i < 1; i++) {
Payload myPayload = new Payload();
myPayload.setPacket(fillPacket(40));
executeClientJob(myPayload, 5000);
}
Payload stopPayload = new Payload();
stopPayload.setRepeat(false);
executeClientJob(stopPayload, 5000);
}
private static void testInteractive() {
Payload myPayload;
boolean repeat;
do {
myPayload = readPayloadSettings();
repeat = myPayload.getRepeat();
executeClientJob(myPayload, 5000);
} while (repeat);
}
private static Payload readPayloadSettings() {
Payload ret = new Payload();
int size = 60;
#SuppressWarnings("resource")
Scanner myScanner = new Scanner(System.in);
System.out.println("Please enter a max data packet size. Enter -1 to end the program");
while (true) {
String response = myScanner.next();
if (Long.parseLong(response) >= -1 && Long.parseLong(response) <= 16384) {
size = Integer.parseInt(response);
break;
} else {
System.out.println("Invalid Response. Please enter a value between 1 and 16384.");
}
}
if (size == -1) {
System.out.println("Closing server...");
ret.setRepeat(false);
} else {
ret.setPacket(fillPacket(size));
System.out.println("Please enter an amount of data passes.");
while (true) {
String response = myScanner.next();
if (Long.parseLong(response) >= 1) {
ret.setDataPasses(Long.parseLong(response));
break;
} else {
System.out.println("Invalid Response. Please enter a value of 1 or greater.");
}
}
System.out.println("Please enter your client address.");
ret.setClient(myScanner.next());
System.out.println("Please enter a server to connect to.");
ret.setServer(myScanner.next());
}
return ret;
}
public static int[] fillPacket(int size) {
int[] thePacket = new int[size];
int current = 0;
while (current < size) {
for (int counter = 0; counter < 100; counter++) {
if (current < size) {
thePacket[current] = counter;
current++;
}
}
}
return thePacket;
}
public static void main(String[] args) throws ClassNotFoundException {
testInteractive();
//testAutomatic();
}
}
Payload class (with defaults to quick create an automatic test)
import java.io.Serializable;
public class Payload implements Serializable {
private int curr=0;
private long dataPasses=5;
private long time;
private String client="localhost";
private String server="localhost";
private int[] packet=new int[0];
private boolean repeat=true;
public Payload() {
}
public int getCurr() {
return curr;
}
public void setCurr(int curr) {
this.curr = curr;
}
public long getDataPasses() {
return dataPasses;
}
public void setDataPasses(long roundTrips) {
this.dataPasses = roundTrips;
}
public long getTime() {
return time;
}
public void setTime(long nanoTime) {
time = nanoTime;
}
public String getClient() {
return client;
}
public void setClient(String client) {
this.client = client;
}
public String getServer() {
return server;
}
public void setServer(String server) {
this.server = server;
}
public int[] getPacket() {
return packet;
}
public void setPacket(int[] packet) {
this.packet = packet;
}
public boolean getRepeat() {
return repeat;
}
public void setRepeat(boolean r) {
this.repeat = r;
}
public void reset() {
curr=0;
dataPasses=0;
}
public void raisePasses() {
curr++;
}
}

Update data in Java in multiple processes active on the same time

I'm creating a token ring with sensors where every sensor is a process apart. When i start a sensor it communicates with the gateway and gets the list of the actual sensors already on the system .
The problem is that every time i start a new process i want every already existing sensor to get the updated list, so to understand that other sensors have been added and the list is no longer the one they had but a new updated one.(So lets say the processes must always have the same list). I use a server which i call serverSocket which listens for messages. I can make it possible for the server to understand that the list has been changed but what i cant do is how to change the value of the sensorList found on my SensorClient class, to be updated? In the code bellow i show what i'm doing but the sensorList keeps being the old one,not being updated :/ Can anyone please help me? Thank you :)
SensorClient where i start a new process sensor
public class SensorClient {
public static void main(String[] args) throws Exception {
Sensor sensor = new Sensor(type,identificator,portnumber,ipnumber,gatewayAddr,timestamp);
Gson gson = new Gson();
String message = gson.toJson(sensor);
Client c = Client.create();
WebResource r = c.resource("http://localhost:9999/gateway/");
ClientResponse response = r.path("sensors/add").type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, message);
if (response.getStatus() == 200) {
repeat = false;
Type collectionType = new TypeToken<ArrayList<Sensor>>(){}.getType();
ArrayList<Sensor> sensorList = gson.fromJson(response.getEntity(String.class), collectionType);
System.out.println("Starting the sensor ...");
System.out.println("Push exit when you want to delete the sensor!");
int position = 0;
for(int i = 0; i< sensorList.size();i++){ if(sensorList.get(i).getIdentificator().equalsIgnoreCase(sensor.getIdentificator()) ) position = i;
}
sensors.Sensor.simulation(type, identificator);// special thread for sensors simulations
createSensor.getInstance().setPrevNextWhenAdd(position,sensorList);
serverSocket serverSocket = new serverSocket(portnumber,sensorList,position,sensorList.get(position).getNext());
serverSocket.start();
StopSensor stopSensor = new StopSensor(identificator,portnumber,position,sensorList);
stopSensor.start();
oneSensor s = new oneSensor(portnumber,sensorList);
s.start();
} else {
repeat = true;
count +=1;
System.out.println("Error. Wrong data! ");
}
}
while (repeat );
}
}
}
The serverSocket thread
public class serverSocket extends Thread {
public int port,nextPort;
ArrayList<gateway.Sensor> sensorList;
public static int position;
public serverSocket(int port, ArrayList<gateway.Sensor> sensorList,int position,int nextPort) {
this.port = port;
this.nextPort=nextPort;
this.sensorList= sensorList;
this.position=position;}
public void run() {
ServerSocket welcomeSocket;
Socket connectionSocket;
try {
welcomeSocket = new ServerSocket(port);
while (true) {
connectionSocket = welcomeSocket.accept();
receivedMessages thread = new receivedMessages(connectionSocket,sensorList,position,nextPort);
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
System.err.println("Error!!!!!!!!!");
}
}
}
The receivedMessages thread
public class receivedMessages extends Thread {
private BufferedReader inFromClient;
private Socket connectionSocket;
ArrayList<gateway.Sensor> sensorList;
int position,nextPort;
public receivedMessages(Socket socket, ArrayList<gateway.Sensor> sensorList,int position,int nextPort){
connectionSocket = socket;
this.sensorList=sensorList;
this.position=position;
this.nextPort=nextPort;
try {
inFromClient = new BufferedReader( new InputStreamReader(connectionSocket.getInputStream()));
} catch (IOException e) { e.printStackTrace(); }
}
#Override
public void run() {
try {
String message = (inFromClient.readLine().toString());
if (message.startsWith("Next") || message.startsWith("Previous")) {
System.out.println(message);
} else if (message.startsWith("The")) {
System.out.println(message); createSensor.getInstance().setPrevNextWhenDelete(position, sensorList);
} else {// i receive the message that the list has changed
System.out.println(message);
sensorList = createSensor.getInstance().getSensorList();
System.out.println("Updated " + sensorList);}
This class has methods used by gateway to register a sensor when it makes the request
public class createSensor {
private static createSensor instance = null;
private ArrayList<Sensor> sensor = new ArrayList<>();
public int position, prevPosition, nextPosition, prevPort, nextPort;
private createSensor() { }
public static synchronized createSensor getInstance() {
if (instance == null) {
instance = new createSensor();
}
return instance;
}
public synchronized ArrayList insertSensor(String type, String identificator, int port, String id, String gatwayAddr, long timestamp) throws IOException {
sensor.add(new Sensor(type, identificator, port, id, gatwayAddr, timestamp));
return new ArrayList<>(sensor); //
}
}
public synchronized boolean hasMeasurements() {
while (InnerBuffer.getInstance().emptyInnerBuffer())
return false;
return true;
}
public synchronized void setPrevNextWhenDelete(int position,ArrayList<Sensor> sensorList) throws IOException {
//code
}
public synchronized ArrayList<Sensor> getSensorList() {
return new ArrayList<>(sensor);
}
public synchronized int size() {
return sensor.size();
}
public synchronized String returnRecentMeasurement (String id){
String recentMeasurement=null;
for (Sensor sensori : sensor) {
if (sensori.getIdentificator().equalsIgnoreCase(id))
recentMeasurement= InnerBuffer.getInstance().returnRecentMeasurements(id);
else
recentMeasurement = null;}
return recentMeasurement;
}
public synchronized void setPrevNextWhenAdd() throws IOException { //some other code where int position, prevPosition, nextPosition, prevPort, nextPort get their values. }}

Java Thread shuts down together with another one which is completely unrelated

So, I was trying to create a chat for multiple users via client-server communication. Connecting and chatting works quite nicely already, however, if one client disconnects from the server (triggered by the keyword exit as the program is console-based atm because the UI is not yet finished), one of the other ClientIO-Threads shuts down additionally to the one related to the disconnecting client. I just don't have any idea why, as those Threads only handle the output of the client that is sending a message.
I tested the program with 3 clients. It seems that if you close client 1 or 2 (with exit; ID in order of connection, starting at 0), the ClientIO-Thread of client 0 shuts down. If you close client 0, Thread 1 shuts down.
Why does that happen? How do I fix it?
Please go easy on me if there's something wrong about how I put the question, first time I ask myself. Thanks in advance!
Code:
Server:
class Server:
import java.io.*;
import java.net.*;
public class Server extends Thread{
int n = 0;
private Socket angekommenerClient;
private ServerSocket sSocket;
Liste client_Liste;
public Server (int port) {
try {
//System.out.println("konst1");
sSocket = new ServerSocket (port);
//System.out.println("konst2");
client_Liste=new Liste();
}catch (Exception e){e.printStackTrace();}
}
public void run(){
try {
//System.out.println("try");
InputStreamReader isr;
BufferedReader br;
while (true) {
//System.out.println("while");
/**Verbindungsannahme**/
angekommenerClient = sSocket.accept();
System.out.println("accept");
InputStream input=angekommenerClient.getInputStream();
OutputStream output=angekommenerClient.getOutputStream();
/**Übergabe Username**/
isr = new InputStreamReader(input);
br = new BufferedReader(isr);
String username = br.readLine();
/**Datenerfassung**/
client_PC neu = new client_PC(angekommenerClient,output,angekommenerClient.getInetAddress(), n, username);
client_Liste.insert(neu);
n++;
client_Liste.toFirst();
System.out.println("test "+((client_PC)client_Liste.getObject()).getID());
/**Vebindungsaufbau**/
new Connection (neu, new BufferedReader(new InputStreamReader(input)));
}
}catch (Exception e){e.printStackTrace();}
}
class Connection{
private BufferedReader client_input; // vom Client
private client_PC client;
private String client_anwender;
private ClientIO cIO;
public Connection(client_PC c, BufferedReader ci){
client=c;
client_input=ci;
cIO=new ClientIO();
cIO.start();
}
class ClientIO extends Thread{
boolean closed = false;
public void run(){
PrintStream ps = null;
while(!client.getSocket().isClosed() && !closed){
try{
if(client_input.ready()){
if(!client_Liste.isEmpty()){
/**Nachricht einlesen**/
System.out.println("listen");
String msg = client_input.readLine();
System.out.println("Input: "+msg);
/**Abmeldung erfahren**/
if(msg.equals("exit")){
closed = true;
}
/**Nachricht weiterleiten...**/
client_Liste.toFirst();
while(client_Liste.hasAccess()){
client_PC cpc = ((client_PC)client_Liste.getObject());
System.out.println("ID: "+cpc.getID());
/**...außer an sich selbst**/
if(cpc.getID()!=client.getID()){
ps = new PrintStream(cpc.getOutput());
ps.println(client.getUsername() + "(" + client.getID() + "): " + msg);
}
client_Liste.next();
}
System.out.println("finish");
}
}
}catch(Exception e){e.printStackTrace();};
}
/**Offenes schließen**/
if(ps != null){
ps.close();
}
System.out.println("disconnected" + client.getID());
stop();
}
}
}
}
class client_PC:
import java.io.*;
import java.net.*;
public class client_PC{
private Socket client_Socket;
private OutputStream client_Output;
private InetAddress client_IP;
private Object client_Info=null;
private int ID;
private String username;
public client_PC(Socket c_Socket,OutputStream c_Output,InetAddress c_IP, int id, String uname){
client_Socket=c_Socket;
client_Output=c_Output;
client_IP=c_IP;
ID = id;
username = uname;
}
public InetAddress getInetAddress(){
return client_IP;
}
public Socket getSocket(){
return client_Socket;
}
public int getID(){
return ID;
}
public OutputStream getOutput(){
return client_Output;
}
public void setInfo(Object info){
client_Info=info;
}
public Object getInfo(){
return client_Info;
}
public String getUsername(){
return username;
}
}
class Liste:
public class Liste{
private ListElement ListKopf;
private ListElement VorAktuellerZeiger, AktuellerZeiger;
Liste(){
ListKopf=null;
AktuellerZeiger=null;
VorAktuellerZeiger=null;
}
boolean isEmpty(){
return (ListKopf==null);
}
public boolean hasAccess() {
return (!this.isEmpty() && AktuellerZeiger!=null);
}
public void next(){
if (this.hasAccess()){
ListElement Hilf=AktuellerZeiger;
AktuellerZeiger=AktuellerZeiger.naechstes;
VorAktuellerZeiger=Hilf;
}
}
public void toFirst() {
AktuellerZeiger=ListKopf;
VorAktuellerZeiger=null;
}
public void toLast() {
if(!hasAccess())this.toFirst();
if(AktuellerZeiger!=null){
while(AktuellerZeiger.naechstes!=null)
next();
}
}
public Object getObject(){
if (this.hasAccess())
return AktuellerZeiger.Inhalt;
else
return null;
}
public void setObject(Object pObject){
if (pObject!=null && this.hasAccess()){
remove();
insvor(pObject);
}
}
private void insvor(Object x){
ListElement Neu= new ListElement(x,AktuellerZeiger);
if(VorAktuellerZeiger==null){ListKopf=Neu; AktuellerZeiger=Neu;}
else {VorAktuellerZeiger.naechstes=Neu;}
}
private void insnach(Object x){
next();
insvor(x);
}
public void insert(Object pObject){
if (pObject!=null)
insvor(pObject);
}
public void append(Object pObject){
if (pObject!=null){
this.toLast();
if(this.hasAccess())
insnach(pObject);
}
}
public void remove(){
if(AktuellerZeiger!=null){
AktuellerZeiger=AktuellerZeiger.naechstes;
if(VorAktuellerZeiger==null){ListKopf=AktuellerZeiger;}
else {VorAktuellerZeiger.naechstes=AktuellerZeiger;}
}
}
}
class ListElement:
public class ListElement{
protected Object Inhalt;
protected ListElement naechstes;
ListElement (Object x, ListElement n){
Inhalt = x;
naechstes = n;
}
}
Client:
class Client:
import java.io.*;
import java.net.*;
public class Client
{
//String IP = "10.16.139.3";
String IP = "localhost";
String name;
int port = 5000;
Socket socket;
ClientThread t1, t2;
public Client(String n){
name = n;
}
public void main() throws IOException{
/**Socket**/
socket = new Socket(IP, port);
/**Übergabe Name**/
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println(name);
/**Verbindungs-Threads**/
t1 = new ClientThread(System.in, socket.getOutputStream(), true);
t2 = new ClientThread(socket.getInputStream(), System.out, false);
t1.start();
t2.start();
while(t1.isAlive() && t2.isAlive()){}
ps.close();
socket.close();
}
}
class ClientThread:
import java.awt.*;
import java.lang.*;
import java.io.*;
import java.net.*;
public class ClientThread extends Thread{
boolean halt = false, isSender;
InputStream is;
InputStreamReader isr;
BufferedReader br;
String msg;
OutputStream os;
PrintStream ps;
public ClientThread(InputStream s1, OutputStream s2, boolean s)
{
try{
isSender = s;
is = s1;
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
os = s2;
ps = new PrintStream(os);
}catch(Exception e){e.printStackTrace();}
}
public void run(){
while (!halt){
try{
if(br.ready()){
msg = br.readLine();
if(msg != null){
ps.println(msg);
if((msg.equals("exit") || msg.trim().equals("null"))&&isSender){stopp(); stop();}
}
else{
System.out.println("Error msg: "+msg);
}
}
}catch(Exception e){e.printStackTrace();}
}
}
public void stopp(){
halt = true;
}
public void weiter(){
halt = false;
}
}

How do I send a message to a specific client(JAVA)

I want to send a message to a specific client:
/w hey there.
X:(priv)Y:hey there(what X sees in the console)
This is my code.When I type it like the upper example nothing shows neither on the specific client's console neither on the server.I don't understand why,because I also have a list of users that are connect in the Server class.
import java.net.*;
import java.io.*;
public class ServerPeer extends Thread{
Socket _socket;
public ServerPeer(Socket _socket) {
this._socket = _socket;
}
public void sendMessage(String _username,String _message) throws IOException {
ObjectOutputStream _obj = new ObjectOutputStream(
_socket.getOutputStream());
_obj.writeObject(new Message(_username, _message));
_obj.flush();
}
public synchronized void run() {
try
{ ObjectInputStream _ois = new ObjectInputStream(_socket.getInputStream());
Message _message;
while (_socket.isConnected()) {
_message = (Message) _ois.readObject();
String divide=_message.getAll().substring(0,_message.getAll().indexOf(":"));
for(ServerPeer sp:Server.listofpeers)
{
if(_message.getAll().startsWith("exit"))
{
_socket.close();Server.listofpeers.remove(sp);
}
if( !(_message instanceof PrivateMessage))
{
sp.sendMessage(divide,_message.getAll());
System.out.println( _message.getAll());
}
else
{
PrivateMessage privatem=(PrivateMessage)_message;
String receiver=privatem.getReceiver();
for(String s:Server.listofusers)
{
if(s.equals(receiver))
{
sp.sendMessage(divide,privatem.getAll());
System.out.println(privatem.getAll());
break;
}
}
}
}
_ois = new ObjectInputStream(_socket.getInputStream());
}
}catch(IOException e){e.printStackTrace();}
catch(ClassNotFoundException e){e.printStackTrace();}
}
}

Java Thread Don't kill other Threads and wont remove from vector item

I have Vector of threads, and i wanna check all items in this vector. Everyone item is connection of user to server. I wanna "clean" all dead connections.
I can't find where I'm wrong.
Here is it my code :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package server;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.ServerCore.Clients;
/**
*
* #author pisio
*/
public class GrimReaper extends Thread {
private int timeout = LoadSettings.Init().getConfigInt("grimreaper") * 1000; // 1000 ms = 1 sec
public GrimReaper() {
super();
}
public void cleanUserThreads() {
Vector users = ServerCore.users;
if (users.size() < 1) {
return;
}
Iterator iteratr = users.iterator();
while (iteratr.hasNext()) {
Clients user = (Clients) iteratr.next();
System.out.println(user.isAlive());
if (user.getClient().isClosed()) {
user.interrupt();
if (user.isInterrupted()) {
System.out.println("Beshe kiknat");
}
iteratr.remove();
// if (PublicVaribles.Init().systemLevelMesseging() == 2) {
System.out.println("+\t Kicked user ");
// }
}//if is dead
}//while
}//cleanUserThreads;
#Override
public void run() {
try {
while (ServerCore.getServerRunning()) {
cleanUserThreads();
sleep(timeout);
System.out.println("nani na shinigami");
}
} catch (InterruptedException ex) {
Logger.getLogger(GrimReaper.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
package server;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.DB.DataBase;
public class ServerCore extends Thread {
private static ServerCore sc = null;
private int port = LoadSettings.Init().getConfigInt("port");
private int max_connections = LoadSettings.Init().getConfigInt("max_connections");
private String ipServer = LoadSettings.Init().getConfig("ipServer");
private ServerSocket socket;
private static boolean serverRuning = false;
public static Vector users = new Vector();
public GrimReaper shinigami = new GrimReaper();// Shinigami from Japanice is Grim Reaper!
private ServerCore() {
}
#Override
public void run() {
shinigami.start();
try {
socket = new ServerSocket(port, max_connections);
System.out.println("+++\t Server was started at address:" + socket.getLocalSocketAddress() + " with posible max users " + max_connections);
serverRuning = true;
while (serverRuning) {
Socket client = socket.accept();
shinigami.cleanUserThreads();
if (users.size() < max_connections) {
Clients cls = new Clients(client);
cls.start();
users.add(cls);
System.out.println("++\tClient was connected:" + client.toString());
} else {
Clients cls = new Clients(client);
cls.start();
cls.getOutput().println("sorry_no_avable_slot");
cls.getOutput().flush();
cls.interrupt();
}
}
} catch (IOException ex) {
// Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
}
}
//run method
public void sendUserMsg() {
Scanner input = PublicVaribles.Init().inputKeyBord();
System.out.print("Enter UserID/user connection port:");
int userID = input.nextInt();
Iterator iterator = users.iterator();
while (iterator.hasNext()) {
Clients cls = (Clients) iterator.next();
/// System.out.println("Passed user:" + cls.getUserId());
if (cls.getUserId() == userID) {
System.out.print("\nEnter msg:");
String str = input.next();
cls.getOutput().println(str);
System.out.println("+\t" + cls.getUserId() + " get msg :" + str);
}
}
}
//SendUserMsg
public void stopServer() {
statusServer();
serverRuning = false;
try {
socket.close();
} catch (IOException ex) {
Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("+++\t SERVER WAS STOPED !");
}
//Stop server
public void statusServer() {
if (serverRuning) {
System.out.println("+++\t Server running at port:" + port + " with connected users :" + users.size() + "/" + max_connections);
} else {
System.out.println("+++\t Server IS NOT RUNNING!");
}
}
//Status server
public static boolean getServerRunning() {
// function for GrimReaper .... R.I.P :D
return ServerCore.serverRuning;
}
public static ServerCore Init() {
if (ServerCore.sc == null) {
ServerCore.sc = new ServerCore();
}
return ServerCore.sc;
}
// SingleTon
public class Clients extends Thread {
private Socket client;
private int userID;
private Scanner input;
private PrintWriter output;
public Clients(Socket socket) {
client = socket;
userID = socket.getPort();
try {
input = new Scanner(client.getInputStream());
output = new PrintWriter(client.getOutputStream(), true);
} catch (IOException ioEx) {
System.out.println(ioEx.toString());
}
}
public int getUserId() {
return userID;
}
public Scanner getInput() {
return input;
}
public PrintWriter getOutput() {
return output;
}
public Socket getClient() {
return client;
}
}//Clients Class
}
Note: I'm assuming Clients extends Thread.
It looks like you might be using interrupt() incorrectly. After calling user.interrupt(), it's up to that thread to check that it has been interrupted by calling Thread.interrupted() and terminate itself if true. Here's an extremely basic example:
class Clients extends Thread {
#Override
public void run() {
while (!Thread.interrupted()) {
//do work
}
//thread has been interrupted and quits
}
}

Categories