ObjectInputStream / ObjectOutputStream | client that receive and send a lot of objects (Java) - java

I have a problem on my multithreaded server/client project.
The server side is good but the problem is on the client side.
I can send and receive objects every time I want I need to declare an ObjectInputStream and ObjectOutputStream as attributes on my Class and then instantiate them on the constructor
But the problem is that the code is blocking on the ObjectInputStream instantiation.
Here is my code:
Client:
public class agency_auth_gui extends javax.swing.JFrame {
Socket s_service;
ObjectOutputStream out;
ObjectInputStream in;
public agency_auth_gui() {
try {
initComponents();
System.out.println("#Connexion en cours avec le Serveur Bancaire.");
s_service = new Socket("127.0.0.1", 6789);
out = new ObjectOutputStream(new BufferedOutputStream(s_service.getOutputStream()));
in= new ObjectInputStream(new BufferedInputStream(s_service.getInputStream()));
//Authentification du Client GAB
out.writeObject((String) "type:agence");
out.flush();
} catch (UnknownHostException ex) {
Logger.getLogger(agency_auth_gui.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(agency_auth_gui.class.getName()).log(Level.SEVERE, null, ex);
}
}
...
Some automaticaly generated swing code
...
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
try {
// Envoi d'une arraylist exec contenant l'authentification
ArrayList exec = new ArrayList();
exec.add("auth_agent");
exec.add(jTextField1.getText());
exec.add(jTextField2.getText());
out.writeObject((ArrayList) exec);
out.flush();
// Reception de la reponse du serveur pour la fonction authentification
Agent agent = (Agent) in.readObject();
if(agent.getId()==0)
{
System.out.println("null");
}else
{
System.out.println(agent.getId());
}
} catch (IOException ex) {
Logger.getLogger(agency_auth_gui.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(agency_auth_gui.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(agency_auth_gui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(agency_auth_gui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(agency_auth_gui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(agency_auth_gui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new agency_auth_gui().setVisible(true);
}
});
}
// Variables declaration - do not modify
..

According to the JavaDoc for ObjectInputStream:
This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.
Edit
So it appears that you're not receiving anything on the InputStream from the other end.

Clearly your server isn't constructing an ObjectOutputStream when the connection is accepted. Don't defer this step: it will block the client while constructing its ObjectInputStream. See the Javadoc.

Related

EOFException when trying to pass the object through sockets

I am trying to pass an object through sockets, from the server to the client, what happens is that in some PCs it works well, and in others it does not. The object is updated indefinitely, so obviously I use an infinite loop to send the object indefinitely. When trying to execute the client sends the following error:
java -jar PC-CheckClient.jar 192.168.1.71 -console
Successfully established connection with server PC-CHECK
Starting... It may take several seconds
jul 11, 2019 1:34:31 AM com.he.pc.view.Main <init>
GRAVE: null
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at com.he.pc.view.Main.<init>(Main.java:39)
at com.he.pc.view.Main.main(Main.java:93)
This is the code sonde command the object from the server
private void sendData() {
//Declarar, instanciar e inicializar
ObjectOutputStream oos = null;
ServerSocket serverSocket = null;
Socket socket = null;
try {
//Puerto 5000
int puerto = 5000;
serverSocket = new ServerSocket(puerto);
System.out.println("Establishing connection with the PC-CHECK client");
socket = serverSocket.accept();
System.out.println("Successfully established connection");
System.out.println("Starting... It may take several seconds");
oos = new ObjectOutputStream(socket.getOutputStream());
while (true) {
//Obtencion del hardware
this.cpuMain = this.loadCPU();
this.ram = this.loadRAM();
//Envio de datos al pc cliente
oos.writeObject(this.cpuMain);
oos.writeObject(this.ram);
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if(oos != null){
oos.close();
}
if(socket != null){
socket.close();
}
if(serverSocket != null){
serverSocket.close();
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
And here the client receives it
public Main(String ip) {
try {
socket = new Socket(ip, 5000);
System.out.println("Successfully established connection with server PC-CHECK");
System.out.println("Starting... It may take several seconds");
ois = new ObjectInputStream(socket.getInputStream());
while(true){
this.cpu = (CPU)ois.readObject();
Utilities.clear();
System.out.println("CPU: ");
System.out.println(cpu.toString());
this.ram = (RAM) ois.readObject();
System.out.println("RAM: ");
System.out.println(this.ram.toString());
}
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}catch (Exception e){
}finally {
try {
if (socket != null) {
socket.close();
}
if (ois != null) {
ois.close();
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
My question is how can I solve this error, and make sure that all computers work properly?
Thank you

output stream doesn't make a file

The code below is supposed to create and write to a file, but it doesn't create a file in my directory. Everything with the Scanner is working, it scans everything from jTextField perfectly.
OutputStream os;
try {
os = new FileOutputStream("kurinys.dat");
try (DataOutputStream dos = new DataOutputStream(os)) {
Scanner skanuoklisSaugojimui = new Scanner(jTextField1.getText());
while(skanuoklisSaugojimui.hasNextInt()){
int natosAukstis = skanuoklisSaugojimui.nextInt();
dos.writeInt(natosAukstis);
}
}
os.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(Grafika.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Grafika.class.getName()).log(Level.SEVERE, null, ex);
}
Can someone please help me find the problem?
Don't use a nested try, it doesnt have any sense and could case a lot of problems in terms of exception handling.
OutputStream os;
try {
os = new FileOutputStream("kurinys.dat");
}
catch (FileNotFoundException e) {
}
try (DataOutputStream dos = new DataOutputStream(os)) {
Scanner skanuoklisSaugojimui = new Scanner(jTextField1.getText());
while(skanuoklisSaugojimui.hasNextInt()){
int natosAukstis = skanuoklisSaugojimui.nextInt();
dos.writeInt(natosAukstis);
}
}
os.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(Grafika.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Grafika.class.getName()).log(Level.SEVERE, null, ex);
}

ObjectInputStream$BlockDataInputStream.peekByte when using program on internet

I created an application with TCP, it works nice when I used it on a local network with 127.0.0.1 but the server refused to works when a client try to connect to him from an another network.
I don't know what this error means and how to resolve it and I can't anderstand that an application could works only on LAN.
public class Reception {
InputStream inObjet = null;
BufferedReader inString = null;
ObjectInputStream recVec2i = null;
public Reception(Socket socket) {
try {
this.inObjet = socket.getInputStream();
this.inString = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.recVec2i = new ObjectInputStream(inObjet);
} catch (IOException ex) {
Logger.getLogger(Reception.class.getName()).log(Level.SEVERE, null, ex);
}
}
public Vecteur2i recevoir() {
Vecteur2i to = new Vecteur2i();
try {
to = (Vecteur2i) recVec2i.readObject();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Reception.class.getName()).log(Level.SEVERE, null, ex);
to = new Vecteur2i(1000, 1000);
}
return to;
}
public String recevoirString() {
String chaine = "";
try {
chaine = inString.readLine();
} catch (IOException ex) {
Logger.getLogger(Reception.class.getName()).log(Level.SEVERE, null, ex);
}
return chaine;
}
public void fermerReception() {
try {
inString.close();
} catch (IOException ex) {
Logger.getLogger(Reception.class.getName()).log(Level.SEVERE, null, ex);
}
try {
inObjet.close();
} catch (IOException ex) {
Logger.getLogger(Emission.class.getName()).log(Level.SEVERE, null, ex);
}
try {
recVec2i.close();
} catch (IOException ex) {
Logger.getLogger(Reception.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
And here the exception :
avr. 22, 2015 9:33:33 PM Snake.Reception recevoir Grave: null
java.io.EOFException at
java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2597)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1316)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at Snake.Reception.recevoir(Reception.java:41) at
Snake.Partie.cycleDeJeu(Partie.java:55)
Regards,
You can't mix different types of stream via the same socket when one or more of them is buffered, and both BufferedInputStream and ObjectInputStream are buffered. The buffers will 'steal' data from each other. In your case you should do all the I/O via the object stream. It has String-based methods.

Java sockets in threads - no data transfer

I'm trying to create data transfer between server and client. Connection is established, but there is no transfer of data between server and client.
Server side:
public static void CreateServerSocket() {
try {
server = new ServerSocket(9999);
t = new Thread(new SocketServer());
t.start();
} catch (IOException ex) {
Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void closeServer() {
try {
server.close();
} catch (IOException ex) {
Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void sentSide(String side) {
out.print(side);
}
#Override
public void run() {
try {
client = server.accept();
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out.print("test from server");
while (true){
strIn=in.readLine();
System.out.println(strIn);
}
} catch (IOException ex) {
Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
Client side:
public class SocketClient implements Runnable {
static Socket client;
static Thread t;
static PrintWriter out;
static BufferedReader in;
static String strIn;
public static boolean CreateClientSocket(InetAddress ip) {
try {
client = new Socket(ip, 9999);
t = new Thread(new SocketClient());
t.start();
return true;
} catch (UnknownHostException ex) {
Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ex);
return false;
} catch (IOException ex) {
Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
}
public static void closeClient() {
try {
client.close();
} catch (IOException ex) {
Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void run() {
try {
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out.print("test from client");
while (true) {
strIn = in.readLine();
System.out.println(strIn);
DialogMultiplayerStart.setSide(strIn);
}
} catch (IOException ex) {
Logger.getLogger(SocketClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
The problem is that out.print is not sending data. Connection is established, because CreateClientSocket returns true, but neither out.print("test from client/server") is working, nor setSide method. Thanks in advance for your help.
The client starts by doing
out.print("test from client");
and then waits for a whole line from the server:
strIn = in.readLine();
The server starts by doing
out.print("test from server");
and then waits for a whole line from the client:
strIn = in.readLine();
So, both sides are waiting for the other side to send an end of line: deadlock.
Change it to
out.println("test from server");
and
out.println("test from client");
to go a bit further. But you'll then have another problem: both sides read in an infinite loop, and don't send anything more.

java.io.EOFException when trying to perform java socket operations

I'm getting the following exception for the code included below that. This works fine when the while() loop is excluded. Why is this?
Oct 6, 2011 1:19:31 AM com.mytunes.server.ServerHandler run
SEVERE: null
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2552)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at com.mytunes.server.ServerHandler.run(ServerHandler.java:68)
Class ServerHandler:
public class ServerHandler extends Thread {
.
.
.
public ServerHandler(...){
...
}
public void run(){
try {
os = s.getOutputStream();
oos = new ObjectOutputStream(os);
is = s.getInputStream();
ois = new ObjectInputStream(is);
while(true){
msg = (Messenger) ois.readObject();
String methodType = msg.getKey();
//validating various data passed from the serialized object
if(methodType.equals("validateCard")){
} else if(methodType.equals("validatePIN")){
}
}
} catch (SQLException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
} finally{
try {
ois.close();
is.close();
oos.close();
os.close();
s.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Class Server
public class Server{
...
ServerSocket ss;
...
public static void main(String args[]){
Server server = new Server();
server.init();
}
public void init(){
try {
System.out.println("Server started...");
ss = new ServerSocket(port);
System.out.println("Listening on " + ss.getInetAddress() + ":" + ss.getLocalPort());
System.out.println("Waiting for clients...");
while(true){
Socket incoming_socket = ss.accept(); // returns a Socket connection object if received
new ServerHandler(...).start();
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
You keep trying to read objects forever, never breaking out of the loop. When the client closes the connection, the stream will run out of data, and the ObjectInputStream.readObject method will throw the exception you're seeing.
How many objects did you expect to be in the stream, and why are you reading past the end of them?

Categories