Sending multiple data over socket - java

I made a multiplayer snake game which is sending the actual score and health to the opponent over socket. The problem is during the game, the enemies health will be its score.
Example the enemy has 90 health and 15 score. When the enemy get 1 score it health will be 16 and the score remains 15. I think the problem is somewhere in the server:
private boolean listenForServerRequest() {
Socket socket = null;
try {
socket = serverSocket.accept();
dos = new DataOutputStream(socket.getOutputStream());
dos2 = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
dis2 = new DataInputStream(socket.getInputStream());
accepted = true;
System.out.println("Client has requested and joined the game");
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
private boolean connect() {
try {
socket = new Socket(ip, port);
dos = new DataOutputStream(socket.getOutputStream());
dos2 = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
dis2 = new DataInputStream(socket.getInputStream());
accepted = true;
} catch (IOException e) {
System.out.println("Unable to connect to the address: " + ip + ":" + port + " | Starting a server");
return false;
}
System.out.println("Successfully connected to the server.");
return true;
}
private void initializeServer() {
try {
serverSocket = new ServerSocket(port, 8, InetAddress.getByName(ip));
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean getConnected() {
return this.connected;
}
public void sendHealth(SnakeHead snakeHead) {
try {
dos.writeInt(snakeHead.getHealth());
System.out.println(snakeHead.getHealth());
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendScore(SnakeHead snakeHead) {
try {
dos2.writeInt(Globals.getScore());
System.out.println(snakeHead.getHealth());
dos2.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public int getEnemyHealth() {
try{if (dis.available() != 0 ) {
try {
enemyHealth = dis.readInt();
return enemyHealth;
} catch (IOException e) {
e.printStackTrace();
}
}}catch (IOException e){
e.printStackTrace();
}
return enemyHealth;
}
public int getEnemyScore() {
try{if (dis2.available() != 0) {
try {
enemyScore = dis2.readInt();
return enemyScore;
} catch (IOException e) {
e.printStackTrace();
}
}}catch (IOException e){
e.printStackTrace();
}
return enemyScore;
}
Hope someone will find the problem or has any advice! Thanks!

Sending multiple data is not a problem. Socket works in TCP mode in this example so write order = read order. To avoid serialization, I would suggest you to send separated values in form of String and use PrintWriter for this purpose. This would send data in "one shot"
See this example:
try (
Socket echoSocket = new Socket(hostName, portNumber);
PrintWriter out =
new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
// reading
String userInput;
while ((userInput = stdIn.readLine()) != null) {
System.out.println("echo: " + in.readLine());
}
// writing
out.println(int + "," + int); // multiple data
)

With socket.getOutputStream() you will get the same stream each time
You have to send the data in a struct , containing the score and health, or you have to send them separately in sequence (like first the health then the score or vicevesa)

Related

Java how to read with ObjectInputStream

It's my first time working with sockets, in order to get a better understanding of what's going on I decided to build a client server chat application which can support several users.
At first, I used DataInputStream / DataOutputStream to communicate and everything works well. But I would like to switch to an ObjectStream and that's where the problem occurs. Once I replace all the DataInputStream / DataOutputStream by ObjectInputStream / ObjectOutputStream, I'm no longer able to print the retrieved data.
This is the code that I used before, which works (DataStream) :
SERVER:
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF("HI FROM SERVER");
while (!socket.isClosed()) {
try {
if (in.available() > 0) {
String input = in.readUTF();
for (ClientThread thatClient : server.getClients()){
DataOutputStream outputParticularClient = new DataOutputStream(thatClient.getSocket().getOutputStream());
outputParticularClient.writeUTF(input + " GOT FROM SERVER");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
CLIENT:
try {
socket = new Socket("localhost", portNumber);
DataInputStream in = new DataInputStream(socket.getInputStream());
new Thread(()->{
while(!socket.isClosed()){
try {
if (in.available() > 0){
String input = in.readUTF();
System.out.println(getUserName() + " > " + input);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
And this is how I tried to perform the same idea with ObjectStream :
SERVER:
try {
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
while (!socket.isClosed()) {
try {
if (in.available() > 0) {
Message input;
try {
input = (Message)in.readObject();
if (input.equals(null)){
System.err.println("SERVER RETRIEVED NULL OBJECT");
}
for (ClientThread thatClient : server.getClients()){
ObjectOutputStream outputParticularClient = new ObjectOutputStream(thatClient.getSocket().getOutputStream());
outputParticularClient.writeObject(input);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
CLIENT:
try {
socket = new Socket(getHost(), portNumber);
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
new Thread(()->{
while(!socket.isClosed()){
try {
if (in.available() > 0){
Message input = null;
try {
input = (Message)in.readObject();
if (input.equals(null)){
System.err.println("CLIENT RETRIEVED NULL OBJECT");
}
System.out.println("CLIENT " + input.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
I feel like it has something to do with this if statement if (in.available() > 0) but I cannot say precisely what's going on.
available() doesn't do what you may think it does and it is almost never useful in production code (and that's particularly true for ObjectInputStream). The reason you don't receive any data is in fact that in.available() always returns 0 as you already suspected.
As noted in the comments, the StreamCorruptedException is caused by writing to an existing ObjectInputStream that has already been written to using another instance of ObjectOutputStream. Cf. the answer StreamCorruptedException: invalid type code: AC for further explanation.
Here is some quick & dirty example code that has a server echoing the messages from two clients. It's not clean but it may give you an idea how to approach your problem:
public class SO56493162 {
private static final class Message implements Serializable {
private static final long serialVersionUID = 1L;
private static int cnt = 0;
private final int id;
public Message(int id) {
++cnt;
this.id = id;
}
public String toString() {
return "Msg from " + id + " : " + cnt;
}
}
private static final class Client implements Runnable {
private InetSocketAddress addr = null;
private int id = -1;
Client(InetSocketAddress addr, int id) {
this.addr = addr;
this.id = id;
}
public void run() {
int timeout = 3000;
Socket s = null;
try {
s = new Socket();
s.connect(addr, timeout);
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
System.out.println("Client " + id + " connected");
while (true) {
Thread.sleep(new Random().nextInt(2000));
Message hello = new Message(id);
oos.writeObject(hello);
oos.flush();
Message reply = (Message) ois.readObject();
System.out.println("Reply: " + reply.toString());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (Exception ignore) {
}
}
}
}
private static final class Server implements Runnable {
private ServerSocket sock = null;
Server(ServerSocket sock) throws IOException {
this.sock = sock;
}
public void run() {
System.out.println("starting server");
try {
while (true) {
final Socket client = sock.accept();
System.out.println("connection accepted");
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
while (!client.isClosed()) {
try {
Message input = (Message) ois.readObject();
oos.writeObject(input);
oos.flush();
} catch (EOFException eof) {
System.err.println("EOF!");
client.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.setDaemon(true);
t.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) throws IOException, InterruptedException {
final int port = 9876;
Thread ts = new Thread(new Runnable() {
#Override
public void run() {
try {
new Server(new ServerSocket(port)).run();
} catch (Exception e) {
e.printStackTrace();
}
}
});
ts.setDaemon(true);
ts.start();
InetSocketAddress addr = new InetSocketAddress("localhost", port);
for (int i = 0; i < 2; ++i) {
Client cl = new Client(addr, i);
Thread tc = new Thread(cl);
tc.setDaemon(true);
tc.start();
}
Thread.sleep(10000);
System.err.println("done");
}
}

Java Client-Server Socket can only send 1 file [duplicate]

This question already has answers here:
Java multiple file transfer over socket
(3 answers)
Closed 6 years ago.
I am doing a sample client-server socket project where the server sends a file to the client and the client saves it in a destination folder. It works well BUT it only works ONCE. I have to restart the server and reconnect the client in order to send another file.
What am I doing wrong?
Server:
public void doConnect() {
try {
InetAddress addr = InetAddress.getByName(currentIPaddress);
serverSocket = new ServerSocket(4445, 50, addr);
isServerStarted = true;
socket = serverSocket.accept();
inputStream = new ObjectInputStream(socket.getInputStream());
outputStream = new ObjectOutputStream(socket.getOutputStream());
String command = inputStream.readUTF();
this.statusBox.setText("Received message from Client: " + command);
} catch (IOException e) {
e.printStackTrace();
}
}
Method that I use to send the file from server
public void sendFile() {
fileEvent = new FileEvent();
String fileName = sourceFilePath.substring(sourceFilePath.lastIndexOf("/") + 1, sourceFilePath.length());
String path = sourceFilePath.substring(0, sourceFilePath.lastIndexOf("/") + 1);
fileEvent.setDestinationDirectory(destinationPath);
fileEvent.setFilename(fileName);
fileEvent.setSourceDirectory(sourceFilePath);
File file = new File(sourceFilePath);
if (file.isFile()) {
try {
DataInputStream diStream = new DataInputStream(new FileInputStream(file));
long len = (int) file.length();
byte[] fileBytes = new byte[(int) len];
int read = 0;
int numRead = 0;
while (read < fileBytes.length && (numRead = diStream.read(fileBytes, read, fileBytes.length - read)) >= 0) {
read = read + numRead;
}
fileEvent.setFileSize(len);
fileEvent.setFileData(fileBytes);
fileEvent.setStatus("Success");
} catch (Exception e) {
e.printStackTrace();
fileEvent.setStatus("Error");
}
} else {
System.out.println("path specified is not pointing to a file");
fileEvent.setStatus("Error");
}
//Now writing the FileEvent object to socket
try {
outputStream.writeUTF("newfile");
outputStream.flush();
outputStream.writeObject(fileEvent);
String result = inputStream.readUTF();
System.out.println("client says: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
Client
public void connect() {
int retryCount = 0;
while (!isConnected) {
if (retryCount < 5) {
try {
socket = new Socket(currentIPAddress, currentPort);
outputStream = new ObjectOutputStream(socket.getOutputStream());
inputStream = new ObjectInputStream(socket.getInputStream());
isConnected = true;
//connection success
String command = inputStream.readUTF();
if (command.equals("newfile")) {
this.clientCmdStatus.setText("Received a file from Server");
outputStream.writeUTF("Thanks Server! Client Received the file");
outputStream.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
new Thread(new DownloadingThread()).start();
}
} catch (IOException e) {
e.printStackTrace();
retryCount++;
}
} else {
//Timed out. Make sure Server is running & Retry
retryCount = 0;
break;
}
}
}
Code used for downloading file in client
public void downloadFile() {
try {
fileEvent = (FileEvent) inputStream.readObject();
if (fileEvent.getStatus().equalsIgnoreCase("Error")) {
System.out.println("Error occurred ..So exiting");
System.exit(0);
}
String outputFile = destinationPath + fileEvent.getFilename();
if (!new File(destinationPath).exists()) {
new File(destinationPath).mkdirs();
}
dstFile = new File(outputFile);
fileOutputStream = new FileOutputStream(dstFile);
fileOutputStream.write(fileEvent.getFileData());
fileOutputStream.flush();
fileOutputStream.close();
System.out.println("Output file : " + outputFile + " is successfully saved ");
serverResponsesBox.setText("File received from server: " + fileEvent.getFilename());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
In order to get the server accept another (and more) connections, you have to put it into a loop
while(someConditionIndicatingYourServerShouldRun) {
Socker socket = serverSocket.accept();
//respond to the client
}
I'd recommend using a thread pool and submit the processing to the thread pool, i.e. by using an ExecutorService. Further, you should close Resources such as stream when finished, the "try-with-resources" construct helps you with that. So your code might look like this
ServerSocket serverSocket = ...;
ExecutorService threadPool = Executors.newFixedThreadPool(10);
AtomicBoolean running = new AtomicBoolean(true);
while(running.get()) {
Socket socket = serverSocket.accept();
threadPool.submit(() -> {
try(ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
OutputStream os = new ObjectOutputStream(socket.getOutputStream())) {
String command = is.readUTF();
if("shutdown".equals(command)) {
running.set(false);
} else {
this.statusBox.setText("Received message from Client: " + command);
}
} catch (IOException e) {
e.printStackTrace();
}
});
}

TCP client and server, cmd prompt using objectstreams

I have one client file clientRPC.java and server file serverRPC.java. Both communicate using TCP protocol and use objectinput and output stream to transfer data.
my client file:
public class clientRPC {
public static void main(String args[]) {
Socket s = null;
try {
int serverPort = 8888;
s = new Socket("localhost", serverPort);// server name is local host
//initializing input and output streams object and referencing them to get input and output
ObjectInputStream in = null;
ObjectOutputStream out = null;
out = new ObjectOutputStream(s.getOutputStream());
in = new ObjectInputStream(s.getInputStream());
MathsTutor mt = new MathsTutor();
out.writeObject(mt);
out.flush();
System.out.println("Welcome to Maths Tutor Service. The available maths exercises are:\n"
+ "Addition: Enter 'A' or 'a'\n"
+ "Subtraction: Enter 'S' or 's'\n"
+ "Multiplication: Enter 'M' or 'm'\n"
+ "Division: Enter 'D' or 'd'\n"
+ "Enter 'Q' or 'q' to quit");
//System.out.println();
MathsTutor mt1 = (MathsTutor) in.readObject();
String response = in.readUTF();
System.out.println(response);
} catch (UnknownHostException e) {
System.out.println("Socket:" + e.getMessage());
} catch (EOFException e) {
System.out.println("EOF:" + e.getMessage());
} catch (IOException e) {
System.out.println("readline:" + e.getMessage());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
if (s != null) {
try {
s.close();
} catch (IOException e) {
System.out.println("close:" + e.getMessage());
}
}
}
}
}
and my server file :
public class serverRPC extends Thread {
String request;
String response;
public static void main(String args[]) {
try {
int serverPort = 8888;
ServerSocket listen_socket = new ServerSocket(serverPort);
while (true) {
Socket clientSocket = listen_socket.accept();
Connection c = new Connection(clientSocket);
}
} catch (IOException e) {
System.out.println("Listen socket:" + e.getMessage());
}
public serverRPC(String s) {
request = s;
}
}
class Connection extends Thread {
ObjectInputStream in;
ObjectOutputStream out;
Socket clientSocket;
public Connection(Socket aClientSocket) {
try {
clientSocket = aClientSocket;
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
this.start();
} catch (IOException e) {
System.out.println("Connection:" + e.getMessage());
}
}
public void run() {
try {
MathsTutor mt = (MathsTutor) in.readObject();
InetAddress ip = clientSocket.getInetAddress();
System.out.println("The Received Message from Client at address:/" + ip.getHostAddress());
System.out.println("====================================");
MathsTutor mt1 = new MathsTutor();
out.writeObject(mt1);
while(true) {
// Read from input
String command = in.readUTF();
System.out.println(command);
}
//System.out.println();
} catch (EOFException e) {
System.out.println("EOF:" + e.getMessage());
} catch (IOException e) {
System.out.println("readline:" + e.getMessage());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {/*close failed*/
}
}
}
}
The problem is when I run server and then client on cmd, the client side displays the welcome msg and puts cursor on another line for user input but, I can't type anything, the cursor just blinks... I know this might be simple but it has taken already 3 hours for me and I'm stuck in the same thing.
The cursor marked with red keeps blinking but doesn't let me type anything.
You're writing an object with writeObject() and trying to read it with readUTF(). Illogical.
objects written with writeObject() must be read with readObject().
strings written with writeUTF() must be read with readUTF().
primitives written with writeXXX() must be read with readXXX(), for most values of X.

Java, Socket : Send several object of an arrayList one by one, the objectInputStream does not read all of them

Hello everybody and thanks in advance to those who will read that :
I'm trying to send an ArrayList of an object "Profile" (which I made serializable) but one by one (because at the end the List will be filled by other threads but this is not the matter here).
I'm using a socket between a "clientconnexion" (which is the client) and a "clientprocessor" (which is the server). They are in different threads and at the end they will be on different computers.
When I try to do it with the following code (trying to send 50 profiles) I do receive some of them (like the 20 first, or the 30 first, sometimes even all of them or none...) but the clientconnexion stops receiving the profiles at one time...
Here is the code :
The class Profile :
public class Profile implements Serializable {
private static final long serialVersionUID = 2406276545874892098L;
public int id;
public String name;
public Profile(String name, int id){
this.id=id;
this.name=name;
}
}
The class Server (which accept the connexion and start clientprocessor thread, it only start one thread so it isn't really usefull now but it will be after) :
public class serveur {
private int port;
private String host = "0.0.0.0";
private ServerSocket server = null;
private boolean isRunning = true;
public serveur(String pHost, int pPort){
host = pHost;
port = pPort;
try {
server = new ServerSocket(port, 100, InetAddress.getByName(host));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void open(){
Thread t = new Thread(new Runnable(){
public void run(){
while(isRunning == true){
try {
Socket client = server.accept();
client.setTcpNoDelay(true);
Thread t = new Thread(new clientprocessor(client));
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
server = null;
}
}
});
t.start();
}
public void close(){
isRunning = false;
}
}
The class clientprocessor :
public class clientprocessor implements Runnable {
private Socket client;
private BufferedOutputStream bos=null;
private BufferedInputStream bis=null;
private BufferedWriter writer=null;
private BufferedReader reader=null;
private ArrayList<Profile> profilesToSend;
public clientprocessor (Socket client){
this.client = client;
this.profilesToSend=new ArrayList<>();
for (int i=1; i<51; i++){
this.profilesToSend.add(new Profile("test", i));
}
}
public synchronized Profile getProfile () {
Iterator<Profile> itr = this.profilesToSend.iterator();
if (itr.hasNext()){
Profile P = itr.next();
itr.remove();
return P;
}
return null;
}
public void run (){
try {
bos= new BufferedOutputStream (client.getOutputStream());
bis= new BufferedInputStream (client.getInputStream());
writer=new BufferedWriter(new OutputStreamWriter(bos));
reader=new BufferedReader(new InputStreamReader(bis));
ObjectOutputStream oos=new ObjectOutputStream(bos);
Profile P;
while ((P = this.getProfile())!=null) {
writer.write(0); //when the client receive a zero, e knows he will receive a profile
writer.flush();
oos.writeObject(P);
oos.flush();
System.out.println("clientprocessor : profile written (" + P.name + " " +P.id +")");
int i=reader.read(); //Waiting to receive a one to be sure that the object was received
System.out.println("clientprocessor : integer received : " +i);
}
System.out.println("--------clientprocessor : all profiles sent--------");
writer.write(1); //when the client receive a one he knows he will not receive profiles anymore
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
writer.close();
reader.close();
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The class clientconnexion (which is supposed to be on another computer at the end) :
public class clientconnexion implements Runnable {
private Socket connexion;
private BufferedOutputStream bos=null;
private BufferedInputStream bis=null;
private BufferedWriter writer=null;
private BufferedReader reader=null;
public clientconnexion(String adress, int port) {
try {
connexion = new Socket(adress, port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
try {
connexion.setTcpNoDelay(true);
bos= new BufferedOutputStream (connexion.getOutputStream());
bis= new BufferedInputStream (connexion.getInputStream());
writer=new BufferedWriter(new OutputStreamWriter(bos));
reader=new BufferedReader(new InputStreamReader(bis));
ObjectInputStream ois = new ObjectInputStream(bis);
int k = reader.read();
String S="clientconnexion : profiles received : ";
while (k==0){
System.out.println("clientconnexion : waiting for an object to read");
Profile P=(Profile)ois.readObject();
S = S + P.name + " " + P.id+ " ; ";
System.out.println(S);
writer.write(1);//the client sends a 1 to the server (clientprocessor)
writer.flush();
k=reader.read();
}
} catch (IOException e) {
System.out.println(e);
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
bis.close();bos.close();reader.close();writer.close();
System.out.println("clientconnexion : streams closed");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And finally the class test which is launching all that :
public class test {
public static String adresse = "localhost";
public static int port = 9028;
public static void main(String[] args) {
serveur serveur = new serveur ("0.0.0.0",port);
System.out.println("--Test : serveur créé");
serveur.open();
System.out.println("Test : serveur ouvert");
Thread tclient1= new Thread(new clientconnexion(adresse, port));tclient1.start();
}
As you can see I tried to setTCPnoDelay but obviously it wasn't the reason of the problem.
Thanks a lot if you read that and if you can run this code and tell me if you have the same problems...
The problem is in clientprocessor class both ObjectOutputStream and BufferedWriter cannot connect to the same stream. Likewise in clientconnexion class both ObjectInputStream and BufferedReader cannot connect to the same stream. The following changes should work
clientprocessor class
try {
bos= new BufferedOutputStream (client.getOutputStream());
bis= new BufferedInputStream (client.getInputStream());
//writer=new BufferedWriter(new OutputStreamWriter(bos));
reader=new BufferedReader(new InputStreamReader(bis));
ObjectOutputStream oos=new ObjectOutputStream(bos);
Profile P;
while ((P = this.getProfile())!=null) {
//writer.write(0); //when the client receive a zero, e knows he will receive a profile
//writer.flush();
oos.write(0);
oos.flush();
oos.writeObject(P);
oos.flush();
System.out.println("clientprocessor : profile written (" + P.name + " " +P.id +")");
int i=reader.read(); //Waiting to receive a one to be sure that the object was received
System.out.println("clientprocessor : integer received : " +i);
}
System.out.println("--------clientprocessor : all profiles sent--------");
//writer.write(1); //when the client receive a one he knows he will not receive profiles anymore
//writer.flush();
oos.write(1);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//writer.close();
reader.close();
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
clientconnexion class
try {
connexion.setTcpNoDelay(true);
bos= new BufferedOutputStream (connexion.getOutputStream());
bis= new BufferedInputStream (connexion.getInputStream());
writer=new BufferedWriter(new OutputStreamWriter(bos));
//reader=new BufferedReader(new InputStreamReader(bis));
ObjectInputStream ois = new ObjectInputStream(bis);
int k = ois.read();
String S="clientconnexion : profiles received : ";
while (k==0){
System.out.println("clientconnexion : waiting for an object to read");
Profile P=(Profile)ois.readObject();
S = S + P.name + " " + P.id+ " ; ";
System.out.println(S);
writer.write(1);//the client sends a 1 to the server (clientprocessor)
writer.flush();
k=ois.read();
}
} catch (IOException e) {
System.out.println(e);
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
bis.close();
bos.close();
//reader.close();
writer.close();
System.out.println("clientconnexion : streams closed");
} catch (IOException e) {
e.printStackTrace();
}
}

Java Chat System

I'm having problems with broadcasting the messages sent by each client. The server can receive each message from multiple clients but it cannot broadcast it. Error message says connection refused
Client:
public void initializeConnection(){
try {
host = InetAddress.getLocalHost();
try{
// Create file
FileWriter fstream = new FileWriter("src/out.txt", true);
BufferedWriter out = new BufferedWriter(fstream);
out.write(host.getHostAddress()+'\n');
//Close the output stream
out.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
clientSocket = new Socket(host.getHostAddress(), port);
outToServer = new PrintWriter(clientSocket.getOutputStream(), true);
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch(IOException ioEx) {
ioEx.printStackTrace();
}
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==quit){
try {
outToServer.close();
clientSocket.close();
System.exit(1);
} catch (IOException e1) {
e1.printStackTrace();
}
}
else if(e.getSource()==button){
if(outMsgArea.getText()!=null || !outMsgArea.getText().equals("")){
String message = outMsgArea.getText();
outToServer.println(clientName+": "+message);
outMsgArea.setText("");
}
}
}
public void run(){
try {
while(true){
String message = inFromServer.readLine();
System.out.println(message);
inMsgArea.append(message+'\n');
}
} catch (IOException e) {
e.printStackTrace();
}
}
Server:
import java.io.*;
import java.net.*;
import java.util.*;
public class RelayChatServer {
public static int port = 44442;
ServerSocket server;
public void listenSocket(){
try{
server = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Could not listen on port 4444");
System.exit(-1);
}
while(true){
ClientWorker w;
try{
//server.accept returns a client connection
w = new ClientWorker(server.accept());
Thread t = new Thread(w);
t.start();
} catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);
}
}
}
protected void finalize(){
//Objects created in run method are finalized when
//program terminates and thread exits
try{
server.close();
} catch (IOException e) {
System.out.println("Could not close socket");
System.exit(-1);
}
}
public static void main(String[] args) {
new RelayChatServer().listenSocket();
}
}
class ClientWorker implements Runnable {
private Socket client;
//Constructor
ClientWorker(Socket client) {
this.client = client;
}
public void run(){
String line;
BufferedReader in = null;
PrintWriter out = null;
try{
in = new BufferedReader(new
InputStreamReader(client.getInputStream()));
//out = new
// PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("in or out failed");
System.exit(-1);
}
while(true){
try{
line = in.readLine();
//Send data back to client
//out.println(line);
//Append data to text area
if(line!=null && line!=""){
System.out.println(line);
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("out.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
Socket s;
PrintWriter prnt;
while ((strLine = br.readLine()) != null && (strLine = br.readLine()) != "") {
// Print the content on the console
s = new Socket(strLine, 44441);
prnt = new PrintWriter(s.getOutputStream(),true);
prnt.println(line);
System.out.println(strLine);
prnt.close();
s.close();
}
//Close the input stream
//inp.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}catch (IOException e) {
System.out.println("Read failed");
e.printStackTrace();
System.exit(-1);
}
}
}
}
The Exception starts:
java.net.ConnectException: Connection refused: connect
The expanded output looks like:
I'm somewhat confused as to why you attempt to open a new socket (do you intend for this to be sent back to the client?) based on a string you read from a file. Perhaps
s = new Socket(strLine, 44441);
prnt = new PrintWriter(s.getOutputStream(),true);
should be:
prnt = new PrintWriter(client.getOutputStream(),true);
As currently I don't see where you are sending anything back to the client.
Edit: ok try something like the following:
static final ArrayList<ClientWorker> connectedClients = new ArrayList<ClientWorker>();
class ClientWorker implements Runnable {
private Socket socket;
private PrintWriter writer;
ClientWorker(Socket socket) {
this.socket = socket;
try {
this.writer = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException ex) { /* do something sensible */ }
}
public void run() {
synchronized(connectedClients) {
connectedClients.add(this);
}
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) { /* do something sensible */ }
while (true) {
try {
String line = in.readLine();
if (line != null && line != "") {
synchronized (connectedClients) {
for (int i = 0; i < connectedClients.size(); ++i){
ClientWorker client = connectedClients.get(i);
client.writer.println(line);
}
}
}
} catch (IOException e) { /* do something sensible */ }
}
}
}

Categories

Resources