My server closes after one clients disconnects,and I can write only one more message then it crashes.I wonder why,since I only close the client socket when it types "EXIT SERVER" .This is the exception it throws:
java.io.EOFException
This is my code :
import java.net.*;
import java.io.*;
public class ServerPeer extends Thread {
Socket _socket;
String username;
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(":"));
username = divide;
Server.listofusers.add(username);
for (ServerPeer sp : Server.listofpeers) {
if (_message.getAll().contains("EXIT SERVER")) {
Server.listofpeers.remove(sp);
_socket.close();
}
if (_message instanceof PrivateMessage) {
PrivateMessage privm = (PrivateMessage) _message;
for (ServerPeer sp2 : Server.listofpeers) {
if (sp2.username.equals(privm.getReceiver())) {
sp2.sendMessage(divide, privm.getAll());
String priv = privm.getAll().replaceAll("/w", "");
System.out.println(priv);
break;
}
}
} else {
sp.sendMessage(divide, _message.getAll());
System.out.println(_message.getAll());
}
}
_ois = new ObjectInputStream(_socket.getInputStream());
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Server Class:
import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
static ServerConfig _svconfig = new ServerConfig();
public static ArrayList<ServerPeer> listofpeers = new ArrayList<ServerPeer>();
public static ArrayList<String> listofusers = new ArrayList<String>();
public static int i = 0;
// final static int _mysocket;
public static void main(String[] args) {
try {
final int _mysocket = _svconfig.getPORTNumber();
System.out.println("Wainting for clients.....");
ServerSocket _serversocket = new ServerSocket(_mysocket, _svconfig.getCLIENTSNumber());
while (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
Socket _clientsocket = _serversocket.accept();
ServerPeer _serverpeer = new ServerPeer(_clientsocket);
_serverpeer.start();
listofpeers.add(_serverpeer);
}
_serversocket.close();
} catch (MissingKeyException e) {
e.printStackTrace();
} catch (UnknownKeyException e) {
e.printStackTrace();
} catch (InvalidFormatException e) {
e.printStackTrace();
} catch (ConnectException e) {
e.printStackTrace();
} catch (BindException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (SocketException e) {
System.out.println("You have been disconnected");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
EDIT:
Exception thrown in the console of the client who disconnects:
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2328)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2797)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at ClientPeer.serverEcho(ClientPeer.java:35)
at ClientPeer.run(ClientPeer.java:44)
BUILD STOPPED (total time: 1 minute 26 seconds)
From what I can tell i'd guess your code is incorrect, but it hard to tell without more code.
At first glance it seems that if too many people connect to your server you just shut down the entire server not just those connections.
while (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
Socket _clientsocket = _serversocket.accept();
ServerPeer _serverpeer = new ServerPeer(_clientsocket);
_serverpeer.start();
listofpeers.add(_serverpeer);
}
_serversocket.close();
A better approach would be something like the following. If too many users try to connect, just close the users connection.
ServerSocket _serversocket = new ServerSocket(_mysocket, _svconfig.getCLIENTSNumber());
boolean alive = true;
while (alive) {
try {
//Keep accepting connection request
Socket clientRequest = _serversocket.accept();
//Check if too many user are connected
if (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
ServerPeer _serverpeer = new ServerPeer(_clientsocket);
_serverpeer.start();
listofpeers.add(_serverpeer);
}else{
//Reject connection if too many connected
clientRequest.close();
}
} catch (Throwable t) {
t.printStackTrace();
}
}
//When server dead close it down
_serversocket.close();
Hope this helps.
Your code must be exiting after the client thread is terminated, create a thread that has the server accept method that starts the client thread, something like this,
/**
*/
private class ServerListener extends Thread
{
/**
*/
public void run()
{
try
{
Socket clientSocket = socket.accept();
System.out.println("client connected => "+clientSocket.getInetAddress().getHostAddress());
ServerListener th = new ServerListener();
th.start();
ClientThread cth = new ClientThread(clientSocket);
cth.start();
clients.add(cth);
return;
}
catch (Exception e)
{
e.printStackTrace();
//Main.getInsatance().println(e);
//Main.getInstance().println("socket disconnected => "+clientSocket.getInetAddress().getHostAddress());
}
}
}
Related
I need to limit the number of client that can connect to the server . I only want 3 clients that can connect not more.
I tried if else conditions. and some loops.
public class server {
ServerSocket ss;
boolean quite=false;
ArrayList<MultiServerConnection> OurDomainsConnections=new ArrayList<MultiServerConnection>();
public static void main(String[] args) {
new server();
}
public server() {
try {
//TODO use method to take this as an input from user)
ss=new ServerSocket(3333);//here we are using connection 3333 (change as you want
while(!quite)
{
Socket s=ss.accept();//when a connection to the domain is found we accept it
MultiServerConnection OurConnection = new MultiServerConnection(s,this);
OurConnection.start();//Start Thread
OurDomainsConnections.add(OurConnection);//add connection to our Domain Connection
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//make sure its bloody same with client it took my 15 min to realize that XD
}
}
public class MultiServerConnection extends Thread {
Socket s;
DataInputStream din;
DataOutputStream dout;
server ss;
boolean quite=false;
public MultiServerConnection(Socket OurSocket,server OurServer)
{
super("MultiServerConnection");//server connection thread
this.s=OurSocket;
this.ss=OurServer;
}
public void ServerOutClientIn(String OutText)
{
try {
long ThreadID=this.getId();
dout.writeUTF(OutText);
dout.flush();//this is because of a buffer error :<
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void ServerOutAllClientIn(String OutText)
{
for(int i=0;i<ss.OurDomainsConnections.size();i++)
{
MultiServerConnection Connection=ss.OurDomainsConnections.get(i);
Connection.ServerOutClientIn(OutText);
}
}
public void run()
{
try {
din=new DataInputStream(s.getInputStream());
dout=new DataOutputStream(s.getOutputStream());
while(!quite)
{
while(din.available()==0)
{
try {
Thread.sleep(1);//sleep if there is not data coming
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String ComingText=din.readUTF();
ServerOutAllClientIn(ComingText);
}
din.close();
dout.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class MultiClients extends Thread {
Socket s;
DataInputStream din;
DataOutputStream dout;
boolean quite=false;
public ClientData c;
public interface1 GUI;
public MultiClients(Socket OurMultiSocket, interface1 gui)
{
s=OurMultiSocket;
c=new ClientData();
GUI=gui;
}
public void ClientOutServerIn(String Text)
{
//write the line from console to server
try {
if(Text.equals("change channel"))
{
System.out.print("sending changing channel: "+Text+"\n");
dout.writeUTF(Text);
dout.flush();
}
else if(Text.equals("new user"))
{
System.out.print("sending new user: "+ Text+"\n");
dout.writeUTF(Text+":"+c.GetName()+"="+c.GetChannel());
dout.flush();
}
else
{
dout.writeUTF(c.GetChannel()+"="+this.getName()+": "+Text);
dout.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void SetClient(String channel,String Name)
{
c.SetName(Name);
c.SetChannel(channel);
}
public void run()
{
try {
din=new DataInputStream(s.getInputStream());
dout=new DataOutputStream(s.getOutputStream());
while(!quite)
{
try {
while(din.available()==0)
{
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//if there is something just show it on console
//and then go back and do the same
String reply=din.readUTF();
String Chan=ExtractChannel(reply);
String name=ExtractName(reply);
/*if (reply.equals("change channel"))
{
System.out.print("changing channel in body: "+reply+"\n");
//GUI.ClearDisplay();
setChangedChannel();
}*/
if(name.equals("new user"))
{
System.out.print("new user in body: "+reply+"\n");
//GUI.ClearDisplay();
setChannel(reply);
}
else
{
PrintReply(Chan,reply);
}
//System.out.println(reply);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
din.close();
dout.close();
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
din.close();
dout.close();
s.close();
} catch (IOException x) {
// TODO Auto-generated catch block
x.printStackTrace();
}
}
}
public void CloseClient()
{
try {
din.close();
dout.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String ExtractName(String x)
{
String[]Y=x.split(":");
return Y[0];
}
public String ExtractChannel(String X)
{
String[]Y=X.split("=");
return Y[0];
}
public void PrintReply(String Chan,String Rep)
{
if(c.GetChannel().equals(Chan))
{
String []Y=Rep.split("=");
GUI.setDisplay(Y[1]);
//System.out.println(Y[1]+"\n \n \n \n");
}
}
public void setChannel(String x)
{
String []Y=x.split(":");
String []Z=Y[1].split("=");
System.out.print("setting "+Z[0]+" channel to "+Z[1]+"\n");
GUI.setUserInChannel(Z[0]);
}
public void setChangedChannel()
{
GUI.setUserInChannel(c.GetName()+": "+c.GetChannel());
}
class ClientData
{
public String ClientName;
public String channel;
public void SetChannel(String Chan)
{
channel=Chan;
}
public void SetName(String name)
{
ClientName=name;
}
public String GetChannel()
{
return channel;
}
public String GetName()
{
return ClientName;
}
}
}
in this code. more than 5 user can can chat together. i only want to allow 3 user to connect and to chat.
You can use AtomicInteger as a counter to check how many clients you have already connected:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
public class server {
ServerSocket ss;
boolean quite=false;
ArrayList<MultiServerConnection> OurDomainsConnections=new ArrayList<MultiServerConnection>();
final AtomicInteger runningCount = new AtomicInteger(0);
final Integer limit = 3;
public static void main(String[] args) {
new server();
}
public server() {
try {
//TODO use method to take this as an input from user)
ss=new ServerSocket(3333);//here we are using connection 3333 (change as you want
while(!quite)
{
Socket s=ss.accept();//when a connection to the domain is found we accept it
if (runningCount.incrementAndGet() < limit){ //increment number of clients and check
MultiServerConnection OurConnection = new MultiServerConnection(s,this, runningCount::decrementAndGet);
OurConnection.start();//Start Thread
OurDomainsConnections.add(OurConnection);//add connection to our Domain Connection
} else {
runningCount.decrementAndGet();
s.close();
System.out.println("limit exceeded");
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//make sure its bloody same with client it took my 15 min to realize that XD
}
}
interface Callback {
void call();
}
class MultiServerConnection extends Thread {
Socket s;
DataInputStream din;
DataOutputStream dout;
server ss;
boolean quite=false;
final Callback callbackOnFinish;
public MultiServerConnection(Socket OurSocket,server OurServer, Callback callbackOnFinish)
{
super("MultiServerConnection");//server connection thread
this.s=OurSocket;
this.ss=OurServer;
this.callbackOnFinish = callbackOnFinish;
}
public void ServerOutClientIn(String OutText)
{
try {
long ThreadID=this.getId();
dout.writeUTF(OutText);
dout.flush();//this is because of a buffer error :<
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void ServerOutAllClientIn(String OutText)
{
for(int i=0;i<ss.OurDomainsConnections.size();i++)
{
MultiServerConnection Connection=ss.OurDomainsConnections.get(i);
Connection.ServerOutClientIn(OutText);
}
}
public void run()
{
try {
din=new DataInputStream(s.getInputStream());
dout=new DataOutputStream(s.getOutputStream());
while(!quite)
{
while(din.available()==0)
{
try {
Thread.sleep(1);//sleep if there is not data coming
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String ComingText=din.readUTF();
ServerOutAllClientIn(ComingText);
}
din.close();
dout.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
callbackOnFinish.call();
}
}
}
When a new connection is accepted runningCount is atomically increased and value is got by runningCount.incrementAndGet(). Then if value below the limit - new MultiServerConnection is created with a callback. The callback is used for decrementing a counter on exit. If counter equal or above the limit => socket will be closed and error message printed. It is good to have a message passed to the socket.
P.S. I have not reviewed your solution. I've just added the feture you requested.
I want to create a class that contain two socket I.e socket for client1 and socket for client 2 so that they can chat together.
How can I achieve this.When i run above code i am getting stream corrupted exception .
My chat is not working. Can someone help me out ?
Here is my code .
This is client code for making socket request
Client.java
package customChat;
import java.net.*;
import java.io.*;
import java.util.*;
public class Client
{
private String notif = " *** ";
private ObjectInputStream sInput;
private ObjectOutputStream sOutput;
private Socket socket;
private String server, username;
private int port;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
private RemoteAccess access;
Client(String server, int port,RemoteAccess access ) {
this.server = server;
this.port = port;
this.access = access;
}
public boolean start()
{
try
{
socket = new Socket(server, port);
}
catch(Exception ec) {
display("Error connectiong to server:" + ec);
return false;
}
String msg = "Connection accepted " + socket.getInetAddress() + ":" + socket.getPort();
display(msg);
try
{
sInput= new ObjectInputStream(socket.getInputStream());
sOutput = new ObjectOutputStream(socket.getOutputStream());
}
catch (IOException eIO) {
eIO.printStackTrace();
display("Exception creating new Input/output Streams in client: " + eIO);
return false;
}
new ListenFromServer().start();
try
{
sOutput.writeObject(access);
}
catch (IOException eIO) {
display("Exception doing login : " + eIO);
//disconnect();
return false;
}
return true;
}
private void display(String msg)
{
System.out.println(msg);
}
void sendMessage(RemoteAccess msg)
{
try
{
System.out.println("I am writing for :"+msg.getTo()+": msg "+msg.getMsg());
sOutput.writeObject(msg);
}
catch(IOException e) {
display("Exception writing to server: " + e);
}
}
private void disconnect() {
try {
if(sInput != null) sInput.close();
}
catch(Exception e)
{
e.printStackTrace();
}
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {
e.printStackTrace();
}
try{
if(socket != null) socket.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void sendFile()
{
int portNumber = 1502;
String serverAddress = "localhost";
Scanner scan = new Scanner(System.in);
System.out.println("Enter from ");
long from = scan.nextLong();
System.out.println("Enter to");
long to = scan.nextLong();
RemoteAccess access = new RemoteAccess(to,from,"hello");
Client client = new Client(serverAddress, portNumber,access);
if(!client.start())
return;
while(true)
{
System.out.println("Please enter msg:");
System.out.print("> ");
// read message from user
String msg = scan.nextLine();
System.out.println("Sending message");
client.sendMessage(new RemoteAccess(to,from,msg));
}
}
public static void main(String[] args)
{
sendFile();
}
class ListenFromServer extends Thread {
public void run()
{
System.out.println("i am in run method");
while(true)
{
System.out.println("i am in run method 2");
try
{
System.out.println("i am in run method 3");
RemoteAccess access = (RemoteAccess) sInput.readObject();
System.out.println("Message read by:"+access.getFrom());
if(access !=null)
{
System.out.println("Message is :"+access.getFrom());
}
}
catch(IOException e)
{
e.printStackTrace();
System.out.println("Excepion caught while listening from server :"+e);
display(notif + "Server has closed the connection: " + e + notif);
break;
}
catch(ClassNotFoundException e2) {
e2.printStackTrace();
}
}
}
}
}
Server.java
package customChat;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
public class Server {
private SimpleDateFormat sdf;
private int port;
private boolean keepGoing;
private String notif = " *** ";
public static ArrayList<ClientThread> al;
public Server(int port)
{
this.port = port;
sdf = new SimpleDateFormat("HH:mm:ss");
al = new ArrayList<ClientThread>();
}
public void start() {
keepGoing = true;
try
{
ServerSocket serverSocket = new ServerSocket(port);
while(keepGoing)
{
display("Server waiting for Clients on port " + port + ".");
Socket socket = serverSocket.accept();
if(!keepGoing)
break;
ClientThread t = new ClientThread(socket);
Thread t1 =new Thread(t);
System.out.println("Connection initiated by:"+t.access.getFrom());
Server.al.add(t);
t1.start();
}
/*try {
serverSocket.close();
for(int i = 0; i < Server.al.size(); ++i) {
ClientThread tc = Server.al.get(i);
try {
tc.sInput.close();
tc.sOutput.close();
tc.socket.close();
}
catch(IOException ioE) {
ioE.printStackTrace();
}
}
}
catch(Exception e)
{
display("Exception closing the server and clients: " + e);
}*/
}
catch (IOException e) {
String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + "\n";
display(msg);
}
}
/*protected void stop() {
keepGoing = false;
try {
new Socket("localhost", port);
}
catch(Exception e) {
}
}*/
// Display an event to the console
private void display(String msg) {
String time = sdf.format(new Date()) + " " + msg;
System.out.println(time);
}
public static void main(String[] args) {
// start server on port 1500 unless a PortNumber is specified
int portNumber = 1502;
// create a server object and start it
Server server = new Server(portNumber);
server.start();
}
}
ClientThread.java
package customChat;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
/*class ListClient
{
public static ArrayList<ClientThread> al=new ArrayList<>();;
}*/
public class ClientThread implements Runnable {
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
String date;
RemoteAccess access;
public RemoteAccess getAccess() {
return access;
}
public void setAccess(RemoteAccess access) {
this.access = access;
}
// Constructor
ClientThread(Socket socket) {
this.socket = socket;
System.out.println("Thread trying to create Object Input/Output Streams");
try
{
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
System.out.println("CT input Stream :"+sInput);
access = (RemoteAccess) sInput.readObject();
System.out.println(access.getFrom() +"Joined the chat room");
}
catch (IOException e)
{
e.printStackTrace();
System.out.println("Exception creating new Input/output Streams: " + e);
return;
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
date = new Date().toString() + "\n";
}
/*private void close() {
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {
e.printStackTrace();
}
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {
e.printStackTrace();
};
try {
if(socket != null) socket.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
*/
#Override
public void run()
{
System.out.println("List size is :"+Server.al.size());
for(int i=0;i<Server.al.size();i++)
{
try {
System.out.println("Socket input Stream :"+Server.al.get(i).socket.getInputStream());
System.out.println("Socket :"+socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
if(Server.al.get(i).access.getFrom()==access.getTo())
{
System.out.println("I am in if part :"+Server.al.get(i).access.getFrom() +"compare to :"+access.getTo());
PairHandler t = null;
try {
t = new PairHandler(access.getTo(),Server.al.get(i).socket,Server.al.get(i).socket.getInputStream(),Server.al.get(i).socket.getOutputStream(),socket.getOutputStream(),socket.getInputStream(),socket);
} catch (IOException e) {
e.printStackTrace();
}
Thread t1 = new Thread(t);
System.out.println("Connection initiated by in CT:"+access.getFrom());
t1.start();
}
else{
System.out.println("I am in else in CT");
}
}
}
}
PairHandler.java
This is where i am using two client socket
package customChat;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class PairHandler implements Runnable
{
long stbId;
Socket tvsocket;
ObjectInputStream tvsInput;
ObjectOutputStream tvsOutput;
Socket dtsocket;
ObjectInputStream dtsInput;
ObjectOutputStream dtsOutput;
PairHandler(long stbId,Socket tvsocket,Socket dtsocket)
{
this.stbId = stbId;
this.tvsocket = tvsocket;
this.dtsocket = dtsocket;
try
{
tvsOutput = new ObjectOutputStream(tvsocket.getOutputStream());
dtsOutput = new ObjectOutputStream(dtsocket.getOutputStream());
System.out.println("DT output Stream is :"+dtsOutput);
System.out.println("Tv outPut Stream is :"+tvsOutput);
System.out.println("RH input Stream :"+tvsocket.getInputStream());
tvsInput = new ObjectInputStream(tvsocket.getInputStream());
System.out.println("Tv input Stream is :"+tvsInput);
dtsInput = new ObjectInputStream(dtsocket.getInputStream());
System.out.println("DT input Stream is :"+dtsInput);
}
catch (IOException e)
{
e.printStackTrace();
System.out.println("Exception creating in Pair Handler new Input/output Streams: " + e);
return;
}
}
public PairHandler(long to, Socket socket, InputStream inputStream, OutputStream outputStream,
OutputStream outputStream2, InputStream inputStream2, Socket socket2) {
stbId = to;
tvsocket = socket;
dtsocket = socket2;
try{
tvsOutput = new ObjectOutputStream(outputStream);
dtsOutput = new ObjectOutputStream(outputStream2);
System.out.println("DT output Stream is :"+dtsOutput);
System.out.println("Tv input Stream is :"+socket.getInputStream());
System.out.println("DT input Stream is :"+socket2.getInputStream());
tvsInput = new ObjectInputStream(socket2.getInputStream());
System.out.println("Tv input Stream is 2 :"+tvsInput);
dtsInput = new ObjectInputStream(socket2.getInputStream());
System.out.println("DT input Stream is :"+dtsInput);
System.out.println("Tv input Stream is :"+tvsInput);
// TODO Auto-generated constructor stub
}
catch (IOException e)
{
System.out.println("Exception in PH");
e.printStackTrace();
}
}
#Override
public void run()
{
try
{
//dtsInput = new ObjectInputStream(dtsocket.getInputStream());
System.out.println("DT socket :"+dtsInput);
if(dtsInput!=null){
RemoteAccess dtMsg = (RemoteAccess) dtsInput.readObject();
if(dtMsg !=null){
// write to tvscoket
System.out.println("I am here in Pair Handler");
sendTOTv(dtMsg);
}
}
// tvsInput = new ObjectInputStream(tvsocket.getInputStream());
System.out.println("TV socket :"+tvsInput);
if(tvsInput!=null){
RemoteAccess tvmsg = (RemoteAccess) tvsInput.readObject();
if(tvmsg !=null){
// write to dtsocket
sendToDT(tvmsg);
}
}
}
catch (IOException e)
{
e.printStackTrace();
System.out.println("Exception found while msg");
}
catch(ClassNotFoundException e2) {
e2.printStackTrace();
}
}
private void sendToDT(RemoteAccess tvmsg) {
// TODO Auto-generated method stub
// if Client is still connected send the message to it
if(!dtsocket.isConnected())
{
closeDtSocket();
}
try {
dtsOutput.writeObject(tvmsg);
}
catch(IOException e) {
System.out.println("Failed to deliver msg");
}
}
private void closeDtSocket() {
try {
if(dtsOutput != null) dtsOutput.close();
}
catch(Exception e) {
e.printStackTrace();
}
try {
if(dtsInput != null) dtsInput.close();
}
catch(Exception e) {
e.printStackTrace();
};
try {
if(dtsocket != null) dtsocket.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
private void closeTvSocket() {
try {
if(tvsOutput != null) tvsOutput.close();
}
catch(Exception e) {
e.printStackTrace();
}
try {
if(tvsInput != null) tvsInput.close();
}
catch(Exception e) {
e.printStackTrace();
};
try {
if(tvsocket != null) tvsocket.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
private void sendTOTv(RemoteAccess dtMsg) {
// TODO Auto-generated method stub
if(!tvsocket.isConnected())
{
closeTvSocket();
}
try {
tvsOutput.writeObject(dtMsg);
}
catch(IOException e) {
System.out.println("Failed to deliver msg");
}
}
}
RemoteAccess.java
package customChat;
import java.io.File;
import java.io.Serializable;
class RemoteAccess implements Serializable {
private static final long serialVersionUID = 1L;
private long to;
private long from;
private File file;
private String msg;
private int x ;
private int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
RemoteAccess(){
}
RemoteAccess(long to,long from)
{
this.to=to;
this.from=from;
}
RemoteAccess(long to,long from,File file)
{
this.to=to;
this.from=from;
this.file=file;
}
RemoteAccess(long to,long from,int x,int y)
{
this.to=to;
this.from=from;
this.x=x;
this.y=y;
}
RemoteAccess(long to,long from,String msg)
{
this.to=to;
this.from=from;
this.msg=msg;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public long getTo() {
return to;
}
public void setTo(long to) {
this.to = to;
}
public long getFrom() {
return from;
}
public void setFrom(long from) {
this.from = from;
}
}
I supposed you want to customize client1 and client2. So you should create a class for each one :
public class Client1 extends Socket {
public Client1() {
super();
}
//Add stuff to customize
}
public class Client2 extends Socket {
public Client2() {
super();
}
//Add stuff to customize
}
Then create your class that contains your two sockets :
public class ClientDialog {
private Client1 client1;
private Client2 client2;
public ClientDialog() {
client1 = new Client1();
client2 = new Client1();
}
//Dialog between client
}
I am pretty new to writing client/server based apps. both server and client classes are kicked off in threads. New to using Object Output/input streams over tcp aswell. Have never had fun with serialization. In my application I am trying to use Object Input/Output Streaming but it looks like opening them is causing my application dies. The funny thing is that if I comment two lines:
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
Connection works nicely and app proceeds to the next panels etc. But I am still not capable of sending any objects throughout the socket. When I literally try to open those streams. It still connects but app get freezed. I 've got two questions:
first: is it better to use serialization
second: if I can use Object streaming, how should I open them? Can I do it inside the server/client thread?
Thanks for Your time
Here is the code of ClientApp:
public void run()
{
while (true)
{
try // odswiezanie co sekunde
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
try // polaczenie
{
if (connecting)
{
socket = new Socket(hostIP, port);
JOptionPane.showMessageDialog(null, "Connection established!");
connected = true;
connecting = false;
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
JOptionPane.showMessageDialog(frame, "Unknown server!");
connected = false;
}
catch (IOException e)
{
JOptionPane.showMessageDialog(frame,"An Error occured while trying to connect to the server!");
e.getMessage();
e.printStackTrace();
connected = false;
}
catch (IllegalThreadStateException e)
{
e.printStackTrace();
}
try // odbior obiektow
{
if(connected)
{
while(!opponentIsReady){
System.out.println("wszedlem do connected!(klient) ");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do klienta!");
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
Do you use Serializable interface for the Map object ?
If you still frozen at a step, its maybe because you try to read object (from server or client) and you didn't send it by the other side. While the object is not read it will wait for content.
I dont know how work your server, but you read response twice when oppenentReady is false.
if (inStream.readObject() != null) {
if (inStream.readObject() instanceof Boolean) {
//...
}
}
If this is not the expected behavior, you should store it in local variable.
Once again, this's smt I want to implement(in steps)
1. user choose to open connection(he becomes a server and waits for a client
to connect) - done.
2. second user choose to connect(becomes a client and connects to the
second player(server) - done.
3. Both get message that the connection is established and they are moved
to the next Panel where they do specific operations - done.
4.When anyone of them finishes, I want to tell it to the second guy
(it is represented by a boolean local varable) - here comes the problem.
5. When both have finished, they should be moved to the next Panel where
they play.(before they start playing, Maps that they have set in the previous Panel
should be sent to each other.
Next steps I can handle if Only I knew maybe not how to send those informations
but where to place sending code because it seems to be in the wrong place. Here is the full code of client/server classes:
connecting - is set to true in the other class after pushing the button.
iAmready - is set to true when player finishes setting up the map and should be sent to opponent,
because it triggers a specific operation by setting opponentIsReady to true when obtained.
public class ClientApp implements Runnable
{
public static String hostIP = "127.0.0.1";
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = false;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public final Frame frame;
public static Map mapToGet;
public static Map mapToSend;
public ClientApp(Frame parent)
{
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run()
{
while (true)
{
try // odswiezanie co sekunde
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
try // polaczenie
{
if (connecting)
{
socket = new Socket(hostIP, port);
JOptionPane.showMessageDialog(null, "Connection established!");
connected = true;
connecting = false;
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
JOptionPane.showMessageDialog(frame, "Unknown server!");
connected = false;
}
catch (IOException e)
{
JOptionPane.showMessageDialog(frame,"An Error occured while trying to connect to the server!");
e.getMessage();
e.printStackTrace();
connected = false;
}
catch (IllegalThreadStateException e)
{
e.printStackTrace();
}
try // odbior obiektow
{
if(connected)
{
FileOutputStream out = new FileOutputStream("/tmp/message.ser");
outStream = new ObjectOutputStream(out);
FileInputStream in = new FileInputStream("/tmp/message.ser");
inStream = new ObjectInputStream(in);
while(!opponentIsReady){
System.out.println("wszedlem do connected!(klient) ");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do klienta!");
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady && iAmReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}
inStream.close();
outStream.close();
in.close();
out.close();
}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
public static void connectionEstablished(Frame frame)
{
frame.remove(frame.connectPanel);
frame.getContentPane().add(frame.settingPanelForClient);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame)
{
frame.remove(frame.settingPanelForClient);
frame.getContentPane().add(frame.opponentsMove);
frame.validate();
frame.repaint();
}
public static Map getMap()
{
try
{
if (connected)
if (inStream.readObject() != null && inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static void sendMap()
{
if (connected)
if (mapToSend != null)
{
try
{
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
public class ServerApp implements Runnable
{
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = false;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ServerSocket hostServer = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public static Map mapToGet;
public static Map mapToSend;
final Frame frame;
public ServerApp(Frame parent)
{
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run()
{
while(true)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e) {}
try
{
if (connecting)
{
hostServer = new ServerSocket(port);
socket = hostServer.accept();
connected = true;
connecting = false;
JOptionPane.showMessageDialog(null, "Connection Established!");
frame.settingPanelForServer.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
connected = connecting = false;
}
catch (IOException e)
{
connected = connecting = false;
}
try // odbior obiektow
{
if(connected)
{
while(!opponentIsReady){
System.out.println("wszedlem do connected(server)");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
inStream = new ObjectInputStream(socket.getInputStream());
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do servera!");
outStream = new ObjectOutputStream(socket.getOutputStream());
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady && iAmReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
public static void connectionEstablished(Frame frame)
{
frame.remove(frame.waitPanel);
frame.getContentPane().add(frame.settingPanelForServer);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame)
{
frame.remove(frame.settingPanelForServer);
frame.getContentPane().add(frame.playPanelForServer);
frame.validate();
frame.repaint();
}
public static Map getMap()
{
try
{
if (connected)
if (inStream.readObject() != null && inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static void sendMap()
{
if (connected)
if (mapToSend != null)
{
try
{
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
As i said before, you can not use readObject() more than once for the same object.
Example,
Use:
Object objectRead=inStream.readObject();
if (objectRead != null) {
if (objectRead instanceof Boolean) {
opponentIsReady = Boolean.valueOf(objectRead);
System.out.println(opponentIsReady);
} else if (objectRead instanceof Map) {
mapToGet = (Map) objectRead;
}
}
Instead of:
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
I think you didn't understand how it works:
When the client/server connection is etablished you can use Threads to read or write objects.
I give you code that you can test to understand how it works:
ServerApp:
public class ServerApp implements Runnable {
public static int port = 1000;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ServerSocket hostServer = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public static Map mapToGet;
public static Map mapToSend;
final Frame frame;
private boolean connected = false;
public ServerApp(Frame parent) {
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run() {
// Server initialization side
try {
hostServer = new ServerSocket(port);
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
// Accept will wait until a client try to connect
socket = hostServer.accept();
JOptionPane.showMessageDialog(null, "Connection Established!");
// Init streams when connection is etablished
inStream = new ObjectInputStream(socket.getInputStream());
outStream = new ObjectOutputStream(socket.getOutputStream());
frame.settingPanelForServer.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
connected = true;
} catch (IOException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
}
int x = 0;
// The loop is made to send/receive all messages
while (connected) {
try {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
}
Object o = String.format("I send you a message (%s)", x++);
outStream.writeObject(o);
Object response = inStream.readObject();
System.out.println("Response: " + response);
} catch (IOException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
connected = false;
} catch (ClassNotFoundException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
connected = false;
}
}
System.err.println("Connection closed");
}
public static void connectionEstablished(Frame frame) {
frame.remove(frame.waitPanel);
frame.getContentPane().add(frame.settingPanelForServer);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame) {
frame.remove(frame.settingPanelForServer);
frame.getContentPane().add(frame.playPanelForServer);
frame.validate();
frame.repaint();
}
public static Map getMap() {
try {
if (inStream.readObject() != null && inStream.readObject() instanceof Map) {
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void sendMap() {
if (mapToSend != null) {
try {
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ClientApp:
public class ClientApp implements Runnable {
public static String hostIP = "127.0.0.1";
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = true;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public final Frame frame;
public static Map mapToGet;
public static Map mapToSend;
public ClientApp(Frame parent) {
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run() {
try {
// Client initialization side
socket = new Socket(hostIP, port);
// If the socket connection succeed it pass, else execption is thrown
JOptionPane.showMessageDialog(null, "Connection Established!");
// Initialize streams
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
connected=true;
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
}
// The loop will receive server message and send response
while (connected) {
try {
Object serverMessage = inStream.readObject();
System.out.println("Server sent: " + serverMessage);
Object myResponse = String.format("I received %s", serverMessage);
outStream.writeObject(myResponse);
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
connected=false;
} catch (ClassNotFoundException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
connected=false;
}
}
System.err.println("Connection closed");
}
public static void connectionEstablished(Frame frame) {
frame.remove(frame.connectPanel);
frame.getContentPane().add(frame.settingPanelForClient);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame) {
frame.remove(frame.settingPanelForClient);
frame.getContentPane().add(frame.opponentsMove);
frame.validate();
frame.repaint();
}
public static Map getMap() {
try {
if (connected) {
if (inStream.readObject() != null && inStream.readObject() instanceof Map) {
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void sendMap() {
if (connected) {
if (mapToSend != null) {
try {
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I have a little problem with reading and writing to Sockets in my Server/Client Java application. Server have connection to database. I want to send an object "Employee" consist User Data (Name, Surname, Password) to Server, then Server look up to database about this user and resend to Client information - positive (1) or negative (-1).
First, when I want to send an object Employee, I've got :
"java.net.SocketException: Software caused connection abort: socket write error"
I have my Firewall turned off.
Second, when I want to send and receive just int through writeInt - readInt method for test, I can't to read anything on Server.
What's the problem? Please help.
Code Server:
class ClientCommunication implements Runnable {
private Socket incoming;
public ClientCommunication(Socket clientSocket) {
incoming = clientSocket;
}
public void run() {
try {
synchronized (this) {
try {
serverObjectOutput = new ObjectOutputStream(
incoming.getOutputStream());
serverObjectInput = new ObjectInputStream(
incoming.getInputStream());
} finally {
incoming.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
synchronized(this) {
while (true) {
try{
int operation = serverObjectInput.readInt();
switch(operation) {
case 1:
Employee employee = (Employee) serverObjectInput.readObject();
String SelectUserDataSQL = "SELECT COUNT(*) AS COUNT FROM pracownik where Imie = ? AND Nazwisko = ? AND Haslo = ?";
PreparedStatement CheckEmployeeLogin;
CheckEmployeeLogin = conn.prepareStatement(SelectUserDataSQL);
CheckEmployeeLogin.setString(1, employee.getFirstName());
CheckEmployeeLogin.setString(2, employee.getLastName());
CheckEmployeeLogin.setString(3, new String(employee.getPassword()));
ResultSet resultSQL = CheckEmployeeLogin.executeQuery();
if (resultSQL.next())
if (resultSQL.getInt("COUNT") == 0)
serverObjectOutput.writeInt(1);
else serverObjectOutput.writeInt(-1);
break;
}
} catch(IOException | ClassNotFoundException | SQLException ex)
{
}
}
}
}
}
class ServerStart implements Runnable {
private int portNumber;
public ServerStart(int portNumber) {
this.portNumber = portNumber;
}
public void run() {
try {
conn = getConnection();
stat = conn.createStatement();
} catch (SQLException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
serverSocket = new ServerSocket(portNumber);
} catch (IOException e) {
e.printStackTrace();
}
try {
while (true) {
Socket incoming = serverSocket.accept();
clientSockets.add(incoming);
Runnable r = new ClientCommunication(incoming);
Thread t = new Thread(r);
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Code Client:
public void actionPerformed(ActionEvent e) {
if (isConnected == false) {
String ServerIP = ip.getText().trim();
int ServerPort = Integer
.parseInt(port.getText().trim());
try {
ClientSocket = new Socket(ServerIP, ServerPort);
clientObjectInput = new ObjectInputStream(
ClientSocket.getInputStream());
clientObjectOutput = new ObjectOutputStream(
ClientSocket.getOutputStream());
isConnected = true;
} catch (IOException ex) {
}
synchronized (this) {
try {
ClientLoginFrame login = new ClientLoginFrame();
Employee employee = login.getEmployee();
clientObjectOutput.writeObject(employee);
int result = clientObjectInput.readInt();
if(result == 1)
{
// DO SOMETHING
}
else {
ClientSocket.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
});
}
add an ex.printStackTrace() to see what is happening in your
catch(IOException | ClassNotFoundException | SQLException ex)
Server side, on your ClientCommunication class: it seems you are closing the socket before entering the while loop. So the socket is already closed and cannot send/receive messages. You should NOT call incoming.close() there, but at the end of your run() method.
Like in topic - System out and err streams seems to be "frozen" in catch clause in "update" method of Kernel class. Oddly when I am debuging the project and stop at System.out line I can even remove breakthrough and everything works correct.
Everything except last System.out is executed, it does not work even when I am replacing default System.out.
At the moment I am disconnecting user just after connection is made.
My code, StartServer.java:
public class StartServer {
public static void main (String[] args) {
Kernel kernel = new Kernel(4444);
kernel.run();
while (true) {
kernel.update();
}
}
}
Kernel.java:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Kernel {
ArrayList<Socket> clients;
ServerSocket socket;
public Kernel(int port) {
try {
socket = new ServerSocket(port);
clients = new ArrayList<>();
System.out.println("Server initialized");
} catch (IOException ex) {
Logger.getLogger(StartServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void run() {
Thread thread = new Thread(){
public void run() {
try {
while (true) {
Socket client = socket.accept();
clients.add(client);
System.out.println("New user on the server!");
}
} catch (IOException ex) {
Logger.getLogger(Kernel.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
thread.start();
}
public void update() {
for (int i=0; i<clients.size(); i++) {
Socket s = clients.get(i);
try {
/*String result;
if (s.getInputStream().available()!=0) {
byte[] byteRes = new byte[s.getInputStream().available()];
char[] charRes = new char[s.getInputStream().available()];
s.getInputStream().read(byteRes);
for (int i2=0; i2<charRes.length; i2++) {
charRes[i2] = (char) byteRes[i2];
}
result = String.copyValueOf(charRes);
System.out.println(result);
}*/
throw new IOException();
} catch (IOException ex) {
try {
System.out.println("Client disconnected"); //working only in debug mode
clients.remove(s);
s.close();
i--;
} catch (IOException ex1) {
Logger.getLogger(Kernel.class.getName()).log(Level.SEVERE, null, ex1);
}
}
}
}
}
Change your infinite loop in StartServer class as below:
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
kernel.update();
}
Try to add a
System.out.flush();
after the System.out.println()