Tengo una clase de cliente y servidor, el cliente tiene GUI. Si abro el servidor y luego el cliente, todo está bien. Pero si abro el servidor y dos clientes, los clientes no se envían mensajes entre sí, solo se envían mensajes con un servidor como el cliente de eco. Supongo que estoy saltando algunos detalles en mi código, pero no puedo averiguar dónde me equivoqué.

enter image description here

CLIENTE

package program;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

    public class gui
    {
        private Socket socket        = null;
        private DataInputStream input = null;
        private DataOutputStream out     = null;
        public String data = "0";

        server _server;
        JFrame pencere;
        JButton button;
        JTextArea area;
        JTextField type;
        public gui(){


            try
            {
                socket = new Socket("127.0.0.1",4000);
                System.out.println("Connected");

                // takes input from terminal
                input = new DataInputStream(socket.getInputStream());

                // sends output to the socket
                out = new DataOutputStream(socket.getOutputStream());
            }
            catch(UnknownHostException u)
            {
                System.out.println(u);
            }
            catch(IOException i)
            {
                System.out.println(i);
            }



            pencere = new JFrame("oxChat");
            pencere.setSize(640,480);
            pencere.setLayout(null);
            button = new JButton("gönder");
            button.addActionListener( new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent e)
                {
                    try {
                        out.writeUTF(type.getText());
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            });
            area = new JTextArea();
            type = new JTextField();
            pencere.add(type);
            pencere.add(area);
            pencere.add(button);
            area.setBounds(0,0,640,350);
            type.setBounds(0,370,640,25);
            button.setBounds(640/2-80/2,400,80,30);
            pencere.setVisible(true);
            pencere.setResizable(false);
            pencere.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            new Thread (new dagitici(socket,this)).start();
        }

        public static void main(String[] args) throws IOException {
            gui app = new gui();
        }

        String getData(){
            return data;
        }
        void setData(String dataa){
            this.data = dataa;
            area.append(this.data+"\n");
        }

    }

    class dagitici extends Thread{
        private Socket socket        = null;
        private DataInputStream input = null;
        private DataOutputStream out     = null;
        gui g;
        public String okunan="";
        public dagitici(Socket socket,gui g){
            this.socket = socket;
            this.g = g;
        }
        @Override
        public void run() {

            try {
                input = new DataInputStream(socket.getInputStream());
                out = new DataOutputStream(socket.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }

            while(true){
                try {
                    System.out.println("a");
                    okunan=input.readUTF();
                    g.setData(okunan);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

SERVIDOR

package program;

// A Java program for a Server
import com.sun.jdi.PathSearchingVirtualMachine;

import javax.swing.*;
import java.net.*;
import java.io.*;

public class server
{
    private Socket socket;
    private ServerSocket server;
    public static   String data;
    // constructor with port
    public void start(int port){
        try {
            server = new ServerSocket(port);
            while(true){
                socket = server.accept();
                new Thread (new ConnectionHandler(socket)).start();
            }
        }catch(IOException i){

        }
    }

    public static void main(String[] args) {
        server _server = new server();
        _server.start(4000);
    }
}

class ConnectionHandler extends Thread{
    gui app;
    private String data;
    private Socket       socket = null;
    private DataInputStream in   = null;
    private DataOutputStream out     = null;
    public ConnectionHandler(Socket socket){
        this.socket=socket;
    }
    @Override
    public void run() {
        try
        {
            System.out.println("Waiting for a client ...");
            System.out.println("Client accepted");
            in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
            out = new DataOutputStream(socket.getOutputStream());

            String line = "";

            // reads message from client until "Over" is sent
            while (!line.equals("Over"))
            {
                try
                {
                    line = in.readUTF();
                    out.writeUTF(line);
                }
                catch(IOException i)
                {
                    System.out.println(i);
                }
            }
            System.out.println("Closing connection");

            // close connection
            socket.close();
            in.close();
        }
        catch(IOException i)
        {
            System.out.println(i);
        }
    }
    public String getServerData(){
        return  data;
    }
}
0
ShooterLens Aim 29 oct. 2019 a las 19:44

1 respuesta

La mejor respuesta
  • Agregue un List<ConnectionHandler> a su clase de servidor:

    List<ConnectionHandler> clients = new ArrayList<>();
    
  • Y por si acaso, una cerradura:

    Object lock = new Object();
    
  • Entonces necesitamos agregar cualquier nuevo cliente conectado a esa lista:

    socket = server.accept();
    ConnectionHandler client = new ConnectionHandler(this, socket)
    synchronized (lock) {
        clients.add(client);
    }
    new Thread(client).start();
    
  • Ahora solo necesitamos un método para distribuir todos los mensajes entrantes en la clase del servidor:

    void distributeMessage(String message) {
        List<ConnectionHandler> clientsCopy;
        synchronized (lock) {
            clientsCopy = new ArrayList<>(clients);
        }
        for (ConnectionHandler client : clientsCopy) {
            client.sendMessage(message);
        }
    }
    
  • Ahora necesitamos cambiar ConnectionHandler, y comenzamos limpiando los campos:

    private Socket socket;
    private DataInputStream in;
    private DataOutputStream out;
    private server server;
    

    Esos son todos los campos que necesitamos.

  • A continuación, necesitamos cambiar el constructor de esta clase:

    public ConnectionHandler(server server, Socket socket) {
        this.server = server;
        this.socket = socket;
        this.in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
        this.out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    }
    

    Todos los campos deben inicializarse en el constructor si es posible.

  • Luego tenemos que agregar nuestro nuevo método sendMessage(String message):

    public void sendMessage(String message) {
        try {
            out.writeUTF(message);
            out.flush();
        } catch (IOException e) {
            // TODO: Here you HAVE to check if the connection was closed
            // And if it was closed, call a method in the server class to
            // remove this client.
            e.printStackTrace();
        }
    }
    
1
Johannes Kuhn 29 oct. 2019 a las 17:33