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

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;
}
}

Related

Player can't connect to server in Java

I am currently programming an online chess game and wanted to host multiple server on 1 PC. It also works when I play with two players, but if I start a third player, it can't connect to server.
The code for the player:
public Socket socket;
public int PlayerID;
public ReadFromServer rfs;
public WriteToServer wts;
public void connectToServer(){
for (int i = 1;i <=3 ;i++ ) {
try {
socket = new Socket("localhost",(1000+i));
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
PlayerID = in.readInt();
System.out.println("You are Player Number:"+PlayerID);
if(PlayerID == 1){
System.out.println("Waiting for Oponent...");
}
rfs = new ReadFromServer(in);
wts = new WriteToServer(out);
Thread rT = new Thread(rfs);
Thread wT = new Thread(wts);
rT.start();
wT.start();
i = 4;
} catch(IOException e) {
System.out.println("ERROR at: connect to Server");
}
}
}
public static void main(String[] args) {
PlayerFrame pf = new PlayerFrame();
pf.connectToServer();
pf.GUI();
}
The Server code:
import java.io.*;
import java.net.*;
import java.net.InetAddress;
public class GameServer {
public int GameNumber = 3;
public ServerSocket ss;
public int numPlayers;
public int maxPlayers;
public Socket socket1;
public Socket socket2;
public ReadFromClient p1read;
public ReadFromClient p2read;
public WriteToClient p1write;
public WriteToClient p2write;
public GameServer[] gs;
public int p1x1,p1x2,p1y1,p1y2,p2x1,p2x2,p2y1,p2y2;
public GameServer(){
gs = new GameServer[GameNumber];
Thread[] server = new Thread[GameNumber];
ServerThread[] thread = new ServerThread[GameNumber];
for (int i = 0;i < gs.length ;i++ ) {
gs[i] = new GameServer((1000+i+1));
thread[i] = new ServerThread(i);
server[i] = new Thread(thread[i]);
server[i].start();
} // end of for
}
public GameServer(int i){
System.out.println("=====Game Server=====");
numPlayers = 0;
maxPlayers = 2;
try {
ss = new ServerSocket(i);
} catch(IOException e) {
System.out.println("ERROR at: Server Construction");
}
}
public void acceptConnections(){
try {
System.out.println("Waiting for connections...");
while (numPlayers < maxPlayers) {
Socket s = ss.accept();
DataInputStream in = new DataInputStream(s.getInputStream());
DataOutputStream out = new DataOutputStream(s.getOutputStream());
numPlayers++;
out.writeInt(numPlayers);
System.out.println("Player Number "+numPlayers+" has connected");
ReadFromClient rfc = new ReadFromClient(numPlayers,in);
WriteToClient wtc = new WriteToClient(numPlayers,out);
if(numPlayers == 1){
socket1 = s;
p1read = rfc;
p1write = wtc;
Thread read1 = new Thread(p1read);
Thread write1 = new Thread(p1write);
read1.start();
write1.start();
}
else{
socket2 = s;
p2read = rfc;
p2write = wtc;
Thread read2 = new Thread(p2read);
Thread write2 = new Thread(p2write);
read2.start();
write2.start();
}
} // end of while
System.out.println("No longer accepting connections");
} catch(IOException e) {
System.out.println("ERROR at: acceptConnections");
}
}
public static void main(String[] args) {
new GameServer();
}
public class ReadFromClient implements Runnable{
public int playerID;
public DataInputStream dataIn;
public ReadFromClient(int pid, DataInputStream in){
playerID = pid;
dataIn = in;
System.out.println("RFC "+playerID+" Runnable created");
}
#Override
public void run(){
try {
while (true) {
if(playerID == 1){
p1x1 = dataIn.readInt();
p1y1 = dataIn.readInt();
p1x2 = dataIn.readInt();
p1y2 = dataIn.readInt();
}
else{
p2x1 = dataIn.readInt();
p2y1 = dataIn.readInt();
p2x2 = dataIn.readInt();
p2y2 = dataIn.readInt();
}
try {
Thread.sleep(25);
} catch(InterruptedException ex) {
System.out.println("ERROR at RFS Run");
}
} // end of while
} catch(IOException e) {
System.out.println("ERROR at: RFS");
}
}
}
public class WriteToClient implements Runnable{
public int playerID;
public DataOutputStream dataout;
public WriteToClient(int pid, DataOutputStream out){
playerID = pid;
dataout = out;
System.out.println("WTC "+playerID+" Runnable created");
}
#Override
public void run(){
try {
while (true) {
if(playerID == 1){
dataout.writeInt(p2x1);
dataout.writeInt(p2y1);
dataout.writeInt(p2x2);
dataout.writeInt(p2y2);
dataout.flush();
}
else{
dataout.writeInt(p1x1);
dataout.writeInt(p1y1);
dataout.writeInt(p1x2);
dataout.writeInt(p1y2);
dataout.flush();
}
try {
Thread.sleep(25);
} catch(InterruptedException ex) {
System.out.println("ERROR at WTC Run");
}
} // end of while
} catch(IOException e) {
System.out.println("ERROR at: WTC run");
}
}
}
public class ServerThread implements Runnable{
public int num;
public ServerThread(int i){
num = i;
}
#Override
public void run(){
gs[num].acceptConnections();
}
}
} // end of class GameServer
I don't get any errors, even though a window doesn't pop up when I run the third player, making.
Have just one ServerSocket and a single loop, and on accepting a client socket start a game running thread using that socket.
ServerSocket serverSocket = ...
ExecutorService executorService = Executors.newFixedThreadPool(4);
while (!executorService .isTerminated()) {
Socket socket = serverSocket.accept();
Runnable gameRun = () -> { ... socket ... };
// like new WorkerThread("...");
executorService .execute(gameRun);
}
executorService .shutdown();
You can do it more neat than here, the thread and passing the socket and such.
The above runs every game conversation in its own thread.
It has one main loop on the server socket, which is crucial; you should not use the same ServerSocket in two threads.
You can easily being overrung by a DoS attack (Denial of Service, by hundreds of requests). Just keep an eye on the count of the number of threads.
On request
I cannot code here an entire client-server dialog. For that you
should look at examples, that probably are way better than what
I can write here. Also my code is not compiled.
Some code snippets.
First I would not exchange binary data, but text. That makes developing and especially debugging easier. Also with chess notation everything is almost done.
Runnable gameRun = new GameRun(socket);
executorService .execute(gameRun);
class GameRun implements Runnable, Autoclosable {
final BufferedReader in;
final PrintWriter out
GameRun(Socket socket) {
in = new BufferedReader(
new InputStreamReader(
socket.getInputStream(),
StandardCharsets.UTF_8));
out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream(),
StandardCharsets.UTF_8)));
}
#Override
public void close() {
in.close();
out.close();
}
#Override
public void run() {
for (;;) {
out.println("Your move/action:");
if (!in.ready()) {
out.println("I am awaiting...");
//continue;
}
String line = in.readLine();
out.println("echo " + line);
if (line == null) {
break;
}
}
}
}
The client should do something similar.

TCP Multiple Clients Room

I'm making code for a Server that has multiple clients that joins in it. Here's what the server's looks like.
public class Server {
private final ServerSocket serverSocket;
private static final int PORT = 9000;
private WaitingRoom wroom = new WaitingRoom();
public Server(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
}
public void startServer() throws InterruptedException,Exception{
try {
int count = 0;
while (!serverSocket.isClosed()) {
Socket socket = serverSocket.accept();
System.out.println("A new client has connected!");
ClientHandler clientHandler = new ClientHandler(new Player(count),socket);
Thread thread = new Thread(clientHandler);
thread.start();
count++;
System.out.println(clientHandler.getPlayer().getNickname());
wroom.join(clientHandler.getPlayer());
}
} catch (IOException e) {
closeServerSocket();
}
}
public void closeServerSocket() {
try {
if(serverSocket != null)
serverSocket.close();
}catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException,InterruptedException,Exception{
ServerSocket serverSocket = new ServerSocket(PORT);
Server server = new Server(serverSocket);
server.startServer();
}
}
I've a class named ClientHandler that manages these clients in a thread for each, and i pass it also in the Player class because i will use it for things like: Send msg, Receive msg. That's the ClientHandler class:
public class ClientHandler implements Runnable {
public static ArrayList<ClientHandler> clientHandlers = new ArrayList<>();
private Player player;
private String nickname;
private Socket socket;
private BufferedReader bufferedReader;
private BufferedWriter bufferedWriter;
public ClientHandler(Player player,Socket socket) throws InterruptedException,Exception{
try {
this.socket = socket;
this.bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.bufferedWriter= new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
nickname = this.bufferedReader.readLine();
player.init(nickname, this);
clientHandlers.add(this);
broadcastMessage("SERVER: " + nickname + " è entrato");
} catch (IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
}
}
public Player getPlayer(){
return player;
}
public BufferedWriter getBufferedWriter(){
return bufferedWriter;
}
public BufferedReader getBufferedReader(){
return bufferedReader;
}
#Override
public void run() {
String messageFromClient;
while (socket.isConnected()) {
/* try {
// messageFromClient = bufferedReader.readLine();
} catch (IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
break;
} */
}
}
public void broadcastMessage(String messageToSend) {
for (ClientHandler clientHandler : clientHandlers) {
try {
if (!clientHandler.nickname.equals(nickname)) {
clientHandler.bufferedWriter.write(messageToSend);
clientHandler.bufferedWriter.newLine();
clientHandler.bufferedWriter.flush();
}
} catch (IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
}
}
}
private void writeToClient(String text) throws IOException{
bufferedWriter.write(text);
bufferedWriter.newLine();
bufferedWriter.flush();
}
public void removeClientHandler() {
clientHandlers.remove(this);
broadcastMessage("SERVER: " + nickname + " è uscito");
}
public void closeEverything(Socket socket, BufferedReader bufferedReader, BufferedWriter bufferedWriter) {
removeClientHandler();
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (bufferedWriter != null) {
bufferedWriter.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Now, the problem is: if I want to create a class named "WaitingRoom" for let players to waint until the wait's done. Where and how could I instantiate it? Before the linked code, i was instantiating it in the ClientHandler, but it worked only for a client a time. Here's what i wrote for the WaitingRoom class:
public class WaitingRoom {
private final int MAXPLAYERS = 2;
private ArrayList<Player> players = new ArrayList<Player>();
public ArrayList<Player> getPlayers(){
return players;
}
public void join(Player player) throws IOException,InterruptedException,Exception{
while(!addPlayer(player)){
player.sendMsg("waiting for join");
TimeUnit.SECONDS.sleep(1);
}
waitStart(player);
}
public boolean addPlayer(Player player){
if (players.size() >= MAXPLAYERS) return false;
players.add(player);
return true;
}
public boolean removePlayer(int idPlayer){
for(Player player : players){
if(player.getId() == idPlayer){
players.remove(player);
return true;
}
}
return false;
}
public void waitStart(Player player) throws IOException,InterruptedException,Exception{
if(players.size() < MAXPLAYERS)
player.sendMsg("sei entrato nella stanza d'attesa");
while(players.size() < MAXPLAYERS){
player.sendMsg("(" + players.size() + "/2) in attesa di giocatori...");
TimeUnit.SECONDS.sleep(1);
}
player.sendMsg("Inizio Gioco");
Player[] players2 = new Player[MAXPLAYERS];
for(int i=0;i<MAXPLAYERS;i++){
players2[0] = new Player(players.get(i).getId()).init(players.get(i).getNickname(),players.get(i).getClientHandler());
}
new Gioco(players2);
cleanRoom();
}
public void cleanRoom(){
players.clear();
}}
it's a really basic concept for waiting room and I only need a place where user must to wait before a gameloop. For example i don't really need multiple wainting rooms, one is ok for me, maybe.

How to perform asynchronous data transfer over SSH channel in JSch

I want to perform bitwise asynchronous data transfer over an SSH channel created through JSch. For asynchronous transfer, I am intending to use two threads, one for receiving and another for sending data. How to acheive this?
Following is the best code i could come up with but it is having inheritance problems...
import com.jcraft.jsch.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
class MyThread extends Thread
{
String name;
private PipedInputStream pin;
private PipedOutputStream pout;
Queue q_manager_to_server = new LinkedList();
Queue q_server_to_manager = new LinkedList();
int data;
int temp;
MyThread (String name, PipedInputStream pin, PipedOutputStream pout)
{
super (name);
this.name = name;
this.pin = pin;
this.pout = pout;
}
public void run ()
{
try
{
System.out.print("Starting thread : "+name);
if (getName ().equals ("to_server"))
{
try{
while(true){
data = (byte)pin.read();
System.out.println("Received : "+data);
q_manager_to_server.offer(data);
temp = (int)q_manager_to_server.poll();
if (temp != 0){
System.out.print("Sending : "+temp);
pout.write(temp);
}
}
}
catch(Exception e){
pout.close();
}
}
else
{
// while ((item = pin.read ()) != -1)
// System.out.print ((char) item); // dst reads
System.out.print("Starting thread : "+name);
try{
while(true){
data = (byte)pin.read();
System.out.println("Received : "+data);
q_server_to_manager.offer(data);
temp = (int)q_server_to_manager.poll();
if (temp != 0){
System.out.print("Sending : "+temp);
pout.write(temp);
}
}
}
catch(Exception e){
pout.close();
}
}
}
catch (IOException e)
{
}
}
}
public class ARDAS_manager{
public static void main(String[] arg){
try{
JSch jsch=new JSch();
//jsch.setKnownHosts("/home/foo/.ssh/known_hosts");
String host=null;
if(arg.length>0){
host=arg[0];
}
else{
host=JOptionPane.showInputDialog("Enter username#hostname",
System.getProperty("user.name")+
"#localhost");
}
String user=host.substring(0, host.indexOf('#'));
host=host.substring(host.indexOf('#')+1);
Session session=jsch.getSession(user, host, 2200);
String passwd = JOptionPane.showInputDialog("Enter password");
session.setPassword(passwd);
UserInfo ui = new MyUserInfo(){
public void showMessage(String message){
JOptionPane.showMessageDialog(null, message);
}
public boolean promptYesNo(String message){
Object[] options={ "yes", "no" };
int foo=JOptionPane.showOptionDialog(null,
message,
"Warning",
JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE,
null, options, options[0]);
return foo==0;
}
};
session.setUserInfo(ui);
// It must not be recommended, but if you want to skip host-key check,
// invoke following,
session.setConfig("StrictHostKeyChecking", "no");
//session.connect();
session.connect(); // making a connection with timeout.
Channel channel=session.openChannel("shell");
// Creating PipedStreams
PipedOutputStream pout_server=new PipedOutputStream();
PipedInputStream pin_server=new PipedInputStream();
PipedOutputStream pout_manager=new PipedOutputStream();
PipedInputStream pin_manager=new PipedInputStream();
pout_manager.connect(pin_server);
pout_server.connect(pin_manager);
channel.setInputStream(pin_server);
channel.setOutputStream(pout_manager);
channel.connect(3*1000);
//channel.wait(10);
MyThread manager_to_server = new MyThread ("to_server", pin_manager, pout_server);
MyThread server_to_manager = new MyThread ("to_manager", pin_server, pout_manager);
/* Thread manager_to_server = new Thread(){
public void run(){
while (true){
try{
pout.write();
}
catch(){
System.out.println("[-]Error in sending data");
}
}
}
}
Thread server_to_manager = new Thread(){
public void run(){
while (true){
try{
pin.read();
}
catch(){
System.out.println("[-]Error in receiving data");
}
}
}
}
*/
System.out.print("I am Here!!!");
manager_to_server.setDaemon(false);
manager_to_server.start ();
manager_to_server.join ();
server_to_manager.setDaemon (false);
server_to_manager.start ();
/*
// a hack for MS-DOS prompt on Windows.
channel.setInputStream(new FilterInputStream(System.in){
public int read(byte[] b, int off, int len)throws IOException{
return in.read(b, off, (len>1024?1024:len));
}
});
*/
//channel.connect();
}
catch(Exception e){
System.out.println(e);
}
}
public static abstract class MyUserInfo
implements UserInfo, UIKeyboardInteractive{
public String getPassword(){ return null; }
public boolean promptYesNo(String str){ return false; }
public String getPassphrase(){ return null; }
public boolean promptPassphrase(String message){ return false; }
public boolean promptPassword(String message){ return false; }
public void showMessage(String message){ }
public String[] promptKeyboardInteractive(String destination,
String name,
String instruction,
String[] prompt,
boolean[] echo){
return null;
}
}
}

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
}
}

Data not synchornizing java sockets

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.

Categories