I am writing an app that makes use of Object Output and Input Streams. However I have a problem, because I am not able to send my object properly. I write it to stream, and server gives me a class not found exception, even though both client and server have exactly the same copy of this class (the only difference is the package name) with the same serial id. Here is my class:
import java.io.Serializable;
public class Message implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String username = null;
private String hashedPassword = null;
private Integer code = null;
private String from = null;
private String to = null;
private Object data = null;
public Message() {
}
public Message(Integer code) {
this.code = code;
}
public Message(Integer code, Object data) {
this.code = code;
this.data = data;
}
public Message(String username, String hashedPassword, Integer code,
String from, String to, Object data) {
this.username = username;
this.hashedPassword = hashedPassword;
this.code = code;
this.from = from;
this.to = to;
this.data = data;
}
public Integer getCode() {
return code;
}
//other getters and setters
}
That is the class which object i want to send. Here is the client code:
(It is wirtten just for testing)
public static void main(String[] args) {
try {
Socket s = new Socket("localhost", 5656);
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
Message m = new Message("user3", "123", 100, "2011-06-11 22:22:22",
"2011-06-11 22:22:22", "test");
oos.writeObject(m);
oos.flush();
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
Message n = (Message) ois.readObject();
System.out.print(n.toString());
oos.close();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
and here is part of server code (yes it is multithreaded):
package systemZarzadzaniaReporterami.serwer;
import java.beans.ExceptionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.sql.SQLException;
public class ClientHandler extends Thread {
private ExceptionListener exceptionListener;
private Socket socket;
private String ip;
public ClientHandler(ExceptionListener exceptionListener, Socket socket) {
this.exceptionListener = exceptionListener;
this.socket = socket;
ip = socket.getInetAddress().getHostAddress();
}
public void run() {
Message in = null;
ObjectInputStream inputStream = null;
ObjectOutputStream outputStream = null;
try {
// ClientListener.CONNECTION_COUNTER++;
inputStream = new ObjectInputStream(socket.getInputStream());
in = (Message) inputStream.readObject();
MessageProcessor messageProcessor = new MessageProcessor();
System.out.print(in.getUsername());
outputStream = new ObjectOutputStream(socket.getOutputStream());
Message out = messageProcessor.process(in, ip);
System.out.print(in.getCode().toString());
outputStream.writeObject(out);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
exceptionListener.exceptionThrown(new ServerException(Codes.ERR_CONNECTION_ERROR));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
exceptionListener.exceptionThrown(new ServerException(Codes.ERR_MYSQL_ERROR));
} finally {
if (inputStream != null)
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
exceptionListener.exceptionThrown(new ServerException(Codes.ERR_CONNECTION_ERROR));
}
if (outputStream != null)
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
exceptionListener.exceptionThrown(new ServerException(Codes.ERR_CONNECTION_ERROR));
}
if (socket != null)
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
exceptionListener.exceptionThrown(new ServerException(Codes.ERR_CONNECTION_ERROR));
}
// ClientListener.CONNECTION_COUNTER--;
}
}
}
I am pretty confused now. Because I have no idea why is such thing happening.
What is most important in my opinion that the following code does well when I replace Message with string.
the only difference is the package name
That won't work. The class name (including the package name) must be the same on both sides.
the only difference is the package name
Then they are not the same class. Make sure you have exactly the same class on both sides. That means same package.
Related
I want to send some objects using network. My network I made it using DatagramSocket, DatagramPacket, ByteArrayInputStream, ObjectInputStream, ByteArrayOutputStream and ObjectOutputStream.
When I was trying to send an object using network I got java.io.EOFException and when I handled this exception using try and catch I lost my object.
Server Side
public class GameServer extends Thread {
private DatagramSocket socket;
private DatagramPacket packet;
private byte[] data;
private ByteArrayInputStream bais;
private ObjectInputStream ois;
private ByteArrayOutputStream baos;
private ObjectOutputStream oos;
private Game game;
public GameServer() {
try {
this.socket = new DatagramSocket(1331);
}
catch (SocketException e) {
e.printStackTrace();
}
start();
}
#Override
public void run() {
while (true) {
data = new byte[6400];
packet = new DatagramPacket(data, data.length);
Object object = receive();
if (object instanceof String) {
String message = (String) object;
System.out.println("CLIENT [ " + packet.getAddress().getHostAddress() + " : " + packet.getPort() + " ] >> " + message.trim());
if (message.equalsIgnoreCase("start")) {
game = new Game("Tankies", 1200, 700);
sendObject(game);
}
}
else if (object instanceof State) {
System.out.println("got state");
}
else if (object instanceof Player)
System.out.println("hi player");
}
}
private Object receive() {
bais = new ByteArrayInputStream(data);
try {
socket.receive(packet);
ois = new ObjectInputStream(new BufferedInputStream(bais));
return ois.readObject();
} catch (EOFException e) {
System.out.println("SERVER Got EOFException");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
private void sendData(byte[] data, InetAddress ipAddress, int port) {
DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress, port);
try {
this.socket.send(packet);
}
catch (IOException e) {
e.printStackTrace();
}
}
private void sendObject(Object object) {
baos = new ByteArrayOutputStream(6400);
oos = null;
try {
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
}
catch (IOException e) {
e.printStackTrace();
}
sendData(baos.toByteArray(), packet.getAddress(), packet.getPort());
}
}
Client Side
public class GameClient extends Thread implements Serializable {
private InetAddress ipAddress;
private transient DatagramSocket socket;
private transient DatagramPacket packet;
private byte[] data;
private transient ByteArrayInputStream bais;
private transient ObjectInputStream ois;
private transient ByteArrayOutputStream baos;
private transient ObjectOutputStream oos;
private Game game;
public GameClient(String ipAddress) {
try {
this.socket = new DatagramSocket();
}
catch (SocketException e) {
e.printStackTrace();
}
try {
this.ipAddress = Inet4Address.getByName(ipAddress);
}
catch (UnknownHostException e) {
e.printStackTrace();
}
start();
}
#Override
public void run() {
while (true) {
data = new byte[6400];
packet = new DatagramPacket(data, data.length);
Object object = receive();
if (object instanceof String) {
System.out.println("SERVER >> " + object);
}
else if (object instanceof Game) {
this.game = (Game) object;
this.game.setClient(this);
this.game.start();
}
}
}
private Object receive() {
bais = new ByteArrayInputStream(data);
try {
socket.receive(packet);
ois = new ObjectInputStream(new BufferedInputStream(bais));
return ois.readObject();
}
catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
private void sendData(byte[] data) {
DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress, 1331);
try {
this.socket.send(packet);
}
catch (IOException e) {
e.printStackTrace();
}
}
public void sendObject(Object object) {
baos = new ByteArrayOutputStream(6400);
oos = null;
try {
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
}
catch (IOException e) {
e.printStackTrace();
}
sendData(baos.toByteArray());
}
}
Code to send the object to server
public class MultiplayerState extends State{
private World world;
private Tank myTank, playerTank;
public MultiplayerState(Handler handler) {
super(handler);
}
#Override
public void startState() {
world = new World(handler,"res/worlds/world1.txt");
handler.setWorld(world);
myTank = new Tank(handler, world.getSpawnX(), world.getSpawnY());
handler.getGame().getRender().addObject(world);
handler.getGame().getRender().addObject(myTank);
world.start();
myTank.start();
handler.getGame().getClient().sendObject(handler.getGame().getPlayer());
}
}
handler.getGame().getClient().sendObject(handler.getGame().getPlayer());
This line to send player to server .. some explanation about code .. this is a game using multithreading in java and i want to create simple network to make two different laptops playing this game online because of that i made this network. I created class Handler this is a class to manage all the game, using object instance of Handler class I can get anything in the game and I want to get object instance of Player class to send it to server because I want to do something to make the game online.
I solved this exception by made GameClient object in Game class transient because I don't want to serialize it. What I want is to use this object to send something to server from Game object internally.
I want to check what type of object is sent to the server as there are two types of clients sending object, one which is a Car Driver and another which is a pedestrian. But whenever I use the if(datain.readObject() instanceof Pedestrian or CarDriver) the server doesn't receive any object and no response is sent to the client anymore. Here is my code:
Server
package eece350;
import java.io.*;
import java.net.Socket;
import java.net.ServerSocket;
import java.sql.Array;
import java.util.ArrayList;
import java.util.Scanner;
import java.lang.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.sql.*;
/**
*
* #author user
*/
public class SkillsServer {
private ServerSocket serverSocket;
private void acceptConnections() {
try {
int port = 7171;
serverSocket = new ServerSocket(port);
}
catch (IOException e)
{
System.err.println("ServerSocket instantiation failure");
e.printStackTrace();
System.exit(0);
}
// Entering the infinite loop
while (true) {
try {
// wait for a TCP handshake initialization (arrival
of a "SYN"
// packet)
Socket newConnection = serverSocket.accept();
System.out.println("accepted connection");
// Now, pass the connection socket created above to a thread and
// run it in it
// First create the thread and pass the connection socket to it
// This is a non-blocking function: constructor of the class
// ServerThread
ServerThread st = new ServerThread(newConnection);
// Then, start the thread, and go back to waiting for another
// TCP connection
// This also is not blocking
new Thread(st).start();
}
catch (IOException ioe)
{
System.err.println("server accept failed");
}
}
}
public static void main(String[] args) throws NullPointerException,
ClassNotFoundException, FileNotFoundException, SQLException
{
SkillsServer server = null;
server= new SkillsServer();
// call this function, which will start it all...
server.acceptConnections();
}
// Internal class
class ServerThread implements Runnable
{
private Socket socket;
private ObjectInputStream datain;
private ObjectOutputStream dataout;
private DataOutputStream outToClient;
ServerThread(Socket socket)
{
// Inside the constructor: store the passed object in the data
// member
this.socket = socket;
}
public void run()
{
try
{
// Input and output streams, obtained from the member socket
// object
outToClient = new DataOutputStream(new
BufferedOutputStream(socket.getOutputStream()));
datain = new ObjectInputStream(new
BufferedInputStream(socket.getInputStream()));
//dataout = new ObjectOutputStream(new
BufferedOutputStream(socket.getOutputStream()));
}
catch (IOException e)
{
return;
}
String name="";
Coordinates location;
Coordinates Destination;
int numberofPassenger;
double chargingPerKilometer;
int carCapacity,did;
Regulations regulations;
boolean connectionActive = true;
String reply="";
while (connectionActive)
{
try
{
if(datain.readObject().getClass()==CarDriver.class)
{
String url
="jdbc:sqlserver://localhost:1433"+";databaseName=EECE350Project;Integrated
Security=True";
String userName = "Mahdi";
String password = "admin";
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn =
DriverManager.getConnection(url,userName,password);
Statement stmt = conn.createStatement();
CarDriver CarDriver1 = (CarDriver)datain.readObject();
name=CarDriver1.getName();
location=CarDriver1.getLocation();
Destination=CarDriver1.getDestination();
numberofPassenger=CarDriver1.getNumofPassengers();
chargingPerKilometer=CarDriver1.getChargingPerKilometer();
carCapacity = CarDriver1.getCarCapacity();
regulations = CarDriver1.getRegulations();
did=CarDriver1.getDid();
reply = "I recieved your connection"+name;
outToClient.write(reply.getBytes(),0,reply.length());
outToClient.write("\\n".getBytes(),0,1);
outToClient.flush();
try
{
System.out.println("Closing Socket");
datain.close();
outToClient.close();
socket.close();
}
catch(IOException ioe)
{
System.out.println("Unable to Close Socket");
}
//String query = "Insert Into EECE 350Project
values(name='"+name+"',did="+did+",XLocation="+location.coordinateX+")";
}
else
{
System.out.println("Hey");
Regulations Pedregulations;
int pid=0;
Coordinates Pedlocation;
Coordinates PedDestination;
Pedestrian Pedestrian1 = (Pedestrian)
datain.readObject();
pid = Pedestrian1.pid;
Pedlocation = Pedestrian1.currentLocation;
PedDestination = Pedestrian1.Destination;
reply= "I recieved your connection";
System.out.println(pid);
outToClient.write(reply.getBytes(),0,reply.length());
outToClient.write("\\n".getBytes(),0,1);
outToClient.flush();
//outToClient.writeBytes(reply);
try
{
System.out.println("Closing Socket");
datain.close();
outToClient.close();
socket.close();
}
catch(IOException ioe)
{
System.out.println("Unable to Close Socket");
}
}
}
catch (IOException ex)
{
Logger.getLogger(SkillsServer.class.getName()).log(Level.SEVERE, null, ex);
}
catch (ClassNotFoundException ex)
{
Logger.getLogger(SkillsServer.class.getName()).log(Level.SEVERE, null, ex);
}
catch (SQLException ex)
{
Logger.getLogger(SkillsServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
try
{
System.out.println("closing socket");
datain.close();
dataout.close();
socket.close();
}
catch (IOException e)
{
System.out.print('.');
}
}
}
}
The client code : Pedestrian for example
package eece350;
import java.io.Serializable;
import java.io.*;
import java.net.*;
/**
*
* #author user
*/
public class Pedestrian implements Serializable
{
public int pid=0;
public Coordinates currentLocation;
public Coordinates Destination;
public Regulations preferences;
public Pedestrian(Coordinates currentLocation,Coordinates Destination,int
pid,Regulations preferences)
{
this.pid=pid;
this.Destination=Destination;
this.currentLocation=currentLocation;
this.preferences=preferences;
}
public static void main(String argv[]) throws Exception
{
Socket clientSocket = new Socket("localhost", 7171);
ObjectOutputStream outToServer = new
ObjectOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()));
//ObjectInputStream inFromServer = new
ObjectInputStream(clientSocket.getInputStream());
int pid =0;
double XLocation = 2;
double YLocation = 2;
double XDestination = 4;
double YDestination = 4;
String modifiedSentence = "";
Coordinates currentLocation = new Coordinates(XLocation,YLocation);
Coordinates Destination = new Coordinates(XDestination,YDestination);
Regulations regulations = new Regulations("yes","No","yes","No");
Pedestrian pedestrian1 = new
Pedestrian(currentLocation,Destination,pid,regulations);
outToServer.writeObject(pedestrian1);
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
outToServer.close();
inFromServer.close();
outToServer.flush();
clientSocket.close();
}
}
Please someone help me :(
Effectively you are calling readObject() twice (but there is only one object on the stream).
The problem starts here:
if(datain.readObject().getClass()==CarDriver.class)
With this call, you are consuming the object, but not using it. Then you call readObject() again, which expects another object (but none exists).
Replace with:
Object object = datain.readObject(); // Read it once
if(object.getClass()==CarDriver.class) {
CarDriver carDriver1 = (CarDriver)object;
// process carDriver1;
}
else {
Pedestrian pedestrian1 = (Pedestrian)object;
// process pedestrian1
}
Have you tried:
Object object = datain.readObject();
if (object instanceof CarDriver) {
CarDriver carDriver1 = (CarDriver)object;
// process carDriver1;
}
else if (object instanceof Pedestrian) {
Pedestrian pedestrian1 = (Pedestrian)object;
// process pedestrian1
}
EDIT:
Replace this:
Pedestrian Pedestrian1 = (Pedestrian)datain.readObject();
With:
Pedestrian Pedestrian1 = (Pedestrian)object;
I have made a basic chat application which runs fine on the same PC but I want it to work on different machines as well.
For the sake of simplicity, I have omitted the GUI code. I receive the IP, name, and port from a separate application which passes it to the client's constructor. I have entered the IP and port of the machine on which the server is running.
Client
public class ClientGui extends JFrame implements Runnable, KeyListener, ActionListener
{
private JPanel contentPane;
private Socket socket;
private String name , ip;
private int port;
private JTextField input;
private JTextArea console;
private JButton send;
private String message;
private DateFormat format;
private BufferedReader in;
private PrintWriter out;
private String reply;
public ClientGui(String name, String ip, int port)
{
format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
this.name = name;
this.ip = ip;
this.port = port;
new Thread(this).start();
}
public void run()
{
try {
socket = new Socket(ip, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
while (true) {
out.println(name);
reply = in.readLine();
if (reply.equals("NAME")) {
name = JOptionPane.showInputDialog("Name taken , Enter another");
} else {
input.setEditable(true);
setTitle(name);
break;
}
}
while (true) {
reply = in.readLine();
if (reply.startsWith("MESSAGE")) {
log(reply.substring(7));
}
}
} catch (Exception e) {
try {
out.close();
in.close();
socket.close();
} catch (Exception e2) {
dispose();
System.exit(0);
}
dispose();
System.exit(0);
}
}
}
Server
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashSet;
public class Server implements Runnable
{
private static ArrayList<PrintWriter> writers;
private static HashSet<String> names;
private Socket socket;
private String name;
private String message;
public Server(Socket socket)
{
this.socket = socket;
}
public void run()
{
PrintWriter temp = null;
try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
while (true) {
name = in.readLine();
if (names.contains(name)) {
out.println("NAME");
} else {
out.println("NAMEACCEPTED");
names.add(name);
break;
}
}
writers.add(out);
temp = out;
while(true) {
message = in.readLine();
for (PrintWriter writer : writers) {
writer.println("MESSAGE" + name + " : " + message);
}
}
}
} catch (Exception e) {
try {
names.remove(name);
writers.remove(temp);
socket.close();
} catch (Exception ignored) {
}
}
}
public static void main(String[] args)
{
writers = new ArrayList<>();
names = new HashSet<>();
ServerSocket server = null;
try {
int port = Integer.parseInt(args[0]);
server = new ServerSocket(port);
} catch (Exception e) {
System.out.println("Enter a valid port");
System.exit(0);
}
while (true) {
try {
System.out.println("Waiting for clients....");
new Thread(new Server(server.accept())).start();
System.out.println("Client Received");
} catch (Exception e) {
System.out.println("Server can't accept clients");
break;
}
}
}
}
I think it could be, because
1) you haven't installed the rigth jre-Version on both devices
2) you aren't in the same Network or you haven't forwarded you'r Ip
have you tried to use this in a Virtual box?
(client1 == vbox1, Server == Computer, client2 == vbox2)
hopefully, this helped
Sorry about the inconvenience to all
the problem was with the port i was using when i switched it , it worked on different machines
thanks for all your help
So I have seen a lot of different questions like this but no definitive help, at least to my understanding or my personal application. I am making a socket "chat room" program that allows the user to send images to selected users through a central server. I can establish the clients to connect but when sending an image this error occurs. Here is my code:
Client:
Thread thread = new Thread() {
#Override
public void run() {
try {
s = new Socket("localhost", 4000);
while (s.isConnected()) {
oos = new ObjectOutputStream(s.getOutputStream());
if (!initialized) {
oos.writeObject(identity);
oos.flush();
oos.reset();
initialized = true;
}
baos = new ByteArrayOutputStream(1000);
// Take screenshot
BufferedImage img = new Robot()
.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
// Write img to baos
ImageIO.write(img, "jpg", baos);
// Send image over socket
oos.writeObject(baos.toByteArray());
oos.flush();
oos.reset();
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
Central Server Home:
public Home() {
initComponents();
textView = new Terminal(terminal);
users = new CopyOnWriteArrayList<>();
Thread startServer = new Thread(new ServerStart());
startServer.start();
}
public class ServerStart implements Runnable {
#Override
public void run() {
try {
serverSock = new ServerSocket(4000);
terminal.append("Server started...\n");
while (true) {
// Detect client connection
Socket clientSock = serverSock.accept();
Thread thread = new Thread(new ClientHandler(clientSock));
thread.start();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public class ClientHandler implements Runnable {
Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
User user = new User(socket);
terminal.append(user.getName() + " connected as " + user.getType() + "...\n");
if (user.getType().equals(User.TYPE_01)) {
users.add(user);
} else {
User client = findUser(user);
while(true){
user.sendScreen(client.receiveScreen());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private User findUser(User user) {
for (User client : users) {
if (client.getCompany().equals(user.getCompany())) {
if (client.getName().equals(user.getName())) {
return client;
}
}
}
return null;
}
}
Central Server User:
public static final String TYPE_00 = "VIEWER";
public static final String TYPE_01 = "CLIENT";
private byte[] bytes;
private ObjectInputStream in;
private ObjectOutputStream out;
private String company, name, type;
public User(Socket socket) throws IOException {
this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
setUserType();
}
public void sendScreen(byte[] bytes) {
try {
out.writeObject(bytes);
out.flush();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public byte[] receiveScreen() {
byte[] bytes = null;
try {
bytes = (byte[]) in.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return bytes;
}
public String getCompany() {
return company;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public void setUserType()
{
String[] strings = null;
try{
strings = (String[])in.readObject();
type = strings[0];
company = strings[1];
name = strings[2];
} catch(Exception e){
e.printStackTrace();
}
}
Client Viewer:
Thread thread = new Thread() {
#Override
public void run() {
try {
Socket s = new Socket("localhost",4000);
String[] strings = { TYPE, "Vision", "cadams" };
while (s.isConnected()) {
if(!initialized){
System.out.println("initialized");
oos = new ObjectOutputStream(s.getOutputStream());
oos.writeObject(strings);
oos.flush();
oos.reset();
initialized = true;
}
ois = new ObjectInputStream(s.getInputStream());
byte[] bytes = (byte[]) ois.readObject();
BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
ImageIcon ico = new ImageIcon(
img.getScaledInstance(viewer.getWidth(), viewer.getHeight(), Image.SCALE_SMOOTH));
viewer.setIcon(ico);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
}
I have done some extensive research and know that this could be from my streams looking like a bowl of ramen noodles but I haven't seen any sort of proposal on how to fix it in terms of source. I thank those who can contribute and please let me know if there is anything I can do to further understanding.
Don't keep creating new ObjectInput/OutputStreams. Use the same ones for the life of the socket.
NB while (s.isConnected() isn't valid. It doesn't magically become false when the peer disconnects. You need to handle end of stream and the various socket termination exceptions.
I am working on multi chat in java. I'm kinda new to this socket thing.
There is a problem with my code but I can't find it. I think the problem is in clientSocket.getInputStream(); . I inserted System.out.println before and after this statement. I can't see the second one. It seems that client can connect to port but cannot get inputs from server. If you can help me, I really would be thankful. It has been 3 hours but still I can't find the problem
ClientSide.java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientSide
{
public Socket clientSocket;
public ObjectOutputStream outStream;
public ObjectInputStream inStream;
public String receiveMessage=null,sendMessage=null;
public GuiScreen gui;
public void run()
{
try
{
clientSocket = new Socket("localhost", 2222);
inStream = new ObjectInputStream(clientSocket.getInputStream());
outStream = new ObjectOutputStream(clientSocket.getOutputStream());
outStream.flush();
while(true)
{
try
{
receiveMessage = (String)inStream.readObject();
gui.appendMessage(receiveMessage);
}
catch(ClassNotFoundException classNot)
{System.err.println("data received in unknown format");}
}
}
catch(UnknownHostException unknownHost)
{System.err.println("You are trying to connect to an unknown host!");}
catch(IOException ioException)
{ioException.printStackTrace();}
}
public String readMessage()
{
String text = "";
try
{
text = (String)inStream.readObject();
}
catch (ClassNotFoundException | IOException e)
{e.printStackTrace();}
return text;
}
public void sendMessage(String msg)
{
try
{
outStream.writeObject(msg);
outStream.flush();
}
catch(IOException ioException){ioException.printStackTrace();}
}
public ClientSide()
{}
private void showGui()
{
gui = new GuiScreen(this,"Client Side");
}
public static void main(String[] args)
{
ClientSide client = new ClientSide();
client.showGui();
client.run();
}
}
MultiCheatServer.java
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MultiChatServer
{
public static ClientThread[] clientThreads = new ClientThread[10];
public static int portNumber = 2222;
public static ServerSocket serverSocket = null;
public static Socket clientSocket = null;
public static void openPort()
{
try
{
serverSocket = new ServerSocket(portNumber);
}
catch (IOException e)
{e.printStackTrace();}
}
public static void connectToClients()
{
while(true)
{
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e)
{e.printStackTrace();}
for(int i = 0; i<=9; ++i)
{
if(clientThreads[i] == null)
{
clientThreads[i] = new ClientThread(clientSocket,clientThreads);
clientThreads[i].start();
break;
}
}
}
}
public static void main(String[] args)
{
openPort();
connectToClients();
}
}
ClientThread.java
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.net.Socket;
public class ClientThread extends Thread
{
public ObjectInputStream inStream = null;
public ObjectOutputStream outStream = null;
public Socket clientSocket;
public ClientThread[] clientThreads;
public ClientThread (Socket cSocket,ClientThread[] cThreads)
{
clientSocket = cSocket;
clientThreads = cThreads;
}
public void sendMessage(String msg)
{
try
{
outStream.writeObject(msg);
outStream.flush();
}
catch (IOException e)
{e.printStackTrace();}
}
public String readMessage()
{
String text = null;
try
{
text = (String)inStream.readObject();
}
catch (ClassNotFoundException | IOException e)
{e.printStackTrace();}
return text;
}
public void run()
{
String text;
String name;
try
{
inStream = new ObjectInputStream(clientSocket.getInputStream());
outStream= new ObjectOutputStream(clientSocket.getOutputStream());
outStream.flush();
sendMessage("Name:\n");
name = readMessage().trim();
sendMessage("type /quit if you want to quit\n");
for(int i = 0 ; i <=9 ; ++i)
if(clientThreads[i]!=null && clientThreads[i]!=this)
clientThreads[i].sendMessage(name + "has come\n");
while(true)
{
text = readMessage() ;
if(text.startsWith("/quit"))
break;
for(int i = 0; i<=9; ++i)
if(clientThreads[i] != null)
clientThreads[i].sendMessage("<" + name + ">" + text);
}
for(int i = 0 ;i<=9; ++i)
if(clientThreads[i]!=null && clientThreads[i]!=this)
clientThreads[i].sendMessage(name + " has disconnected\n");
sendMessage("Bye\n");
inStream.close();
outStream.close();
for(int i = 0;i<=9;++i)
if(clientThreads[i]==this)
clientThreads[i] = null;
}
catch (IOException e)
{e.printStackTrace();}
}
}
One problem I see is that you have to decide who creates the input stream first, the server or the client.
ObjectInputStream tries to read a serialization header in its constructor, and if the output stream has not written it yet it will wait. Now both client and server are waiting for the other to "speak" first.