0

I'm trying to make a Client/Server program that uses tcp java connection and im testing it on the same machine (both Server and client) using localhost IP and port 12345.

I use ObjectInputStream and ObjectOutputStream to receive and send messages. Sometimes my program works perfect, it send the right messages as i want, but sometimes (in random time/stage of the program) one of my client "loses" the connection and he gets into an infinite loop printing "null" or "invalid type code:54" without doing any code changes.

Im getting no errors just the server prints "Connection reset" in loop and the client the "null" or "invalid type code:54" from the catch (IOException e).

I will show you just the basic of my Code.

server:

    public static void main(String[] args) {
    //--------BASIC CODE used for connection stuff below----//
         server = new ServerSocket(12345);
         connection =server.accept();
         Thread thread =new Thread(new ClientThread(connection,GRM...));
         thread.start();
         output = new ObjectOutputStream(connection.getOutputStream());
         output.flush();
         input = new ObjectInputStream(connection.getInputStream());
    }
    --------------//---------thread for each client----------//--------------
    do{
           try{
             message=(String) input.readObject();
             if(message.startsWith("SOMENTHING"))//...some tcode
             if(message.equals("SEND")){
                 String message="hi";
                 output.writeObject("Chat:"+message);output.flush();
                 UserW.writeObject(message);UserW.flush();
                 //UserW is an output from another client stored in the server
             }
             catch(ClassNotFoundException classNotFoundException){
                System.out.print("\nUnknown object");
             }catch (IOException e) {
                System.out.println(e.getMessage());
             }    
     }while(!message.equals("DISCONNECT"));

Client:

        public static void main(String[] args) {
        connection=new Socket(InetAddress.getByName("127.0.0.1"),12345);
        //...... same logic with streams......//
        }
        //-------thread that receives from server-----//
        do{
          try{
           String message=(String) input.readObject();
           //.....some code....//
          }catch( ClassNotFoundException classNotFoundException){
            System.out.print("\nUnknown object");
          }catch (IOException e) {
            System.out.println(e.getMessage());
          }
        }while(true);
never give
  • 13
  • 6
  • You seem to be opening two ObjectOutputStream on the same server socket, which is probably causing this error. – Adonis Mar 19 '17 at 20:13
  • I open an ObjectOutputStream for each new connection and i process them in a new thread...if you mean that – never give Mar 20 '17 at 11:49
  • No I mean your server has `output.writeObject; UserW.writeObject;` Which seems to point that one thread (your server) handle two ObjectOutputStream which is not a good idea at all – Adonis Mar 20 '17 at 11:56
  • Ok i see what you mean, but i have seen a tutorial for a chat app and it did the same thing to broadcast the message to the others.The UserW is a reference from another clients socket output STORED in the server....in the other hand my problem appears most when i have to send messages to others so you may have a point there. But how im supposed to send messages to others? – never give Mar 20 '17 at 18:04
  • No need to believe me, check http://stackoverflow.com/a/10777950/4121573 or here: http://stackoverflow.com/a/2395269/4121573 Worst case, you might try an `ObjectOutputStream.reset()` between both calls – Adonis Mar 20 '17 at 18:09
  • One more thing.....might the problem be solved if i use WriteChars instead of WriteObject? *(I'm not trying it yet because i have 1000 lines in my program and i want to be sure first) – never give Mar 20 '17 at 19:46

2 Answers2

0

Why client readObject() sometimes return null

It isn't. readObject() is not returning null. You are printing null in the catch block, because you caught an IOException with no message, possibly EOFException for example, which should cause you to close the socket and break out of the read loop.

The actual issue is a concurrency problem, here:

Thread thread =new Thread(new ClientThread(connection,GRM...));
thread.start();
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());

The output and input variables should be members of ClientThread, not this class, and they should be initialized in ClientThread.run(), not in its constructor, and certainly not here.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I solved my problem, i have already write the answer.I can't understand what u mean probably my knowledge on java isn't so good – never give Apr 06 '17 at 15:17
-1

So i made some tests with another simpler Server/Client program i created and i figured that when the server sends two or more messages simuntaniously the input.read() of the client gets "confused" and wont read the messages properly making the server do "connection reset" and the client give the "invalid code" errors

My solution for that problem (that works) is to create a synchronized method of sending messages to the clients, on Server site, but i dont like it because the Server performance will decrease(i think).As a second solution i was thinking on the client site to make something like a buffer but i don't know if that is possible.

If somebody has a better solution i would loved to hear it.

UPDATE:Best solution is using using BufferedReader for input and a PrintWriter for output,instead of streams.

P.S. A big thank to asettouf, he lead me to the right way.

never give
  • 13
  • 6
  • You only have multiple threads using same streams because of a variable scoping mistake. This solution sequentializes all I/O to all clients. Not at all desirable. – user207421 Apr 04 '17 at 01:13