简体   繁体   中英

Java - TCP client/server using ObjectOutputStream and threading

I am trying to develop some kind of chat application (learning purposes) but when I send my objects from the client to the server only the first one seems to get received. No error is shown or nothing so I don't really know whats wrong.

Server code:

import chattychat.domain.Message;
import chattychat.domain.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;

 /**
 *
 * @author 
 */

public class Server {
private final int PORT;

private ServerSocket server;

public Server(){
    this.PORT = 6565;
}

public Server(int port){
    this.PORT = port;
}


public void listenSocket(){
    try{
        this.server = new ServerSocket(this.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");

        }
    }
}

class ClientWorker implements Runnable {
    private Socket client;
    private ObjectInputStream in;

    //Constructor
    ClientWorker(Socket client) {
        this.client = client;
    }

    public void run(){
        try{
            this.in = new ObjectInputStream(this.client.getInputStream());
            Object obj = this.in.readObject();
            System.out.println("called");
            if(obj instanceof Message){
                Message msg = (Message)obj;
                System.out.println(msg);
            }else if(obj instanceof User){
                User user = (User)obj;
                System.out.println(user);
            }
            System.out.println();
        }catch (IOException e) {
            System.out.println("Read failed");
            //System.exit(-1);
        } catch (ClassNotFoundException ex) {
            System.out.println("Object not found");
            //System.exit(-1);
        }
    }
}

@Override
protected void finalize(){
    try{
        this.server.close();
    } catch (IOException e) {
        System.out.println("Could not close socket");
        System.exit(-1);
    }
}

public static void main(String[] args){
    Server s = new Server();
    //s.communicate();
    s.listenSocket();
}

}

Client code:

import chattychat.domain.Message;
import chattychat.domain.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;

/**
 *
 * @author laurensputseys
 */
public class Client {

    private final int PORT = 6565;
    private String SERVER = "localhost";

    private Socket socket;
    private ObjectInputStream in;
    private ObjectOutputStream out;
    private boolean isConnected;

    public Client(){
        this.isConnected = false;
    }

    public Client(String server){
        this.SERVER = server;
    }

    public String getServer(){
        return this.SERVER;
    }

    public int getPort(){
        return this.PORT;
    }

    public void communicate(Message msg){
        while(!isConnected){
            try{
                this.socket = new Socket(this.getServer(), this.getPort());
                isConnected = true;
                this.out = new ObjectOutputStream(this.socket.getOutputStream());
                this.out.writeObject(msg);
                this.out.flush();
                this.out.close();
            }catch(SocketException se){
                se.printStackTrace();
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }

    public void register(User usr){
        while(!isConnected){
            try{
                this.socket = new Socket(this.getServer(), this.getPort());
                isConnected = true;
                this.out = new ObjectOutputStream(this.socket.getOutputStream());
                this.out.writeObject(usr);
                this.out.flush();
                this.out.close();
            }catch(SocketException se){
                se.printStackTrace();
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }

    public boolean isConnected(){
        return isConnected;
    }

    public static void main(String[] args){
        Client c = new Client();
        User u1 = new User("firstname 1", "lastname1", "testuser");
        User u2 = new User("firstname 2", "lastname2", "Testuser");
        Message m1 = new Message(u1, u2, "Hello from P1 to P2");
        Message m2 = new Message(u2, u1, "Hello from P2 to P1");
        System.out.println("Send 1");
        c.communicate(m1);
        System.out.println("Send 2");
        c.communicate(m2);
        System.out.println("Send 3");
        c.register(u1);
    }
}

message class:

import java.io.Serializable;
import java.util.Objects;

/**
 *
 * @author 
 */
public class Message implements Serializable{

    private static final long serialVersionUID = 7526472295622776147L;
    private User from;
    private User to;
    private String message;

    public Message(User from, User to, String message){
       this.setFrom(from);
       this.setTo(to);
       this.setMessage(message);
    }

    private void setFrom(User from){
        this.from = from;
    }

    private void setTo(User to){
        this.to = to;
    }

    private void setMessage(String message){
        this.message = message;
    }

    public String getMessage(){
        return this.message;
    }

    @Override
    public boolean equals(Object o){
        if(this == o) return true;
        if(o == null || getClass() != o.getClass()) return false;
        Message tmpMsg = (Message)o;
        return this.to.equals(tmpMsg.to) && this.from.equals(tmpMsg.from) && this.getMessage().equals(tmpMsg.getMessage());
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + Objects.hashCode(this.from);
        hash = 59 * hash + Objects.hashCode(this.to);
        hash = 59 * hash + Objects.hashCode(this.message);
        return hash;
    }

    @Override
    public String toString(){
        return "From: " + this.from + " to: " + this.to + " message: " +this.getMessage();
    }
}

User class:

import java.io.Serializable;
import java.util.Objects;

/**
 *
 * @author
 */
public class User implements Serializable{

    private static final long serialVersionUID = 7526456787322776147L;
    private String firstname;
    private String lastname;
    private String password;

    public User(String firstname, String lastname, String password){
        setFirstname(firstname);
        setLastname(lastname);
        setPassword(password);
    }

    private void setFirstname(String firstname){
        this.firstname = firstname; //TODO
    }

    private void setLastname(String lastname){
        this.lastname = lastname; //TODO
    }

    private void setPassword(String password){
        this.password = password; //TODO
    }

    @Override
    public boolean equals(Object o){
        if(this == o) return true;
        if(o == null || getClass() != o.getClass()) return false;
        User tmpUser = (User)o;
        return this.firstname.equals(tmpUser.firstname) && this.lastname.equals(tmpUser.lastname);
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + this.firstname.length();
        hash = 59 * hash + this.lastname.length();
        hash = 59 * hash + this.password.length();
        return hash;
    }

    @Override
    public String toString(){
        return this.firstname + " " + this.lastname;
    }
}

Thanks in advance!

Without reading your code very thoroughly. Your clients communicate methods sets connected to true on the first call. So the while loop will not be entered on the second call to communicate. You should separate connecting to server and sending messages. Also, your client worker thread in server seems to return after one object read. The run method should return when connection is broken, not when one message is read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM