Отправка данных с сервера всем клиентам при программировании сокетов на Java - PullRequest
0 голосов
/ 29 октября 2019

У меня есть класс клиента и сервера, клиент имеет графический интерфейс. Если я открою сервер, а затем клиента, все в порядке. Но если я открою сервер и двух клиентов, клиенты не будут обмениваться сообщениями друг с другом, а будут только обмениваться сообщениями с сервером, как эхо-клиент. Я предполагаю, что прыгаю некоторые детали в своем коде, но я не могу понять, где я ошибаюсь.

enter image description here

КЛИЕНТ

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();
                }
            }
        }
    }

СЕРВЕР

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;
    }
}

1 Ответ

1 голос
/ 29 октября 2019
  • Добавьте List<ConnectionHandler> к вашему классу сервера:

    List<ConnectionHandler> clients = new ArrayList<>();
    
  • И для хорошей меры, блокировка:

    Object lock = new Object();
    
  • Затем нам нужно добавить любого нового подключенного клиента в этот список:

    socket = server.accept();
    ConnectionHandler client = new ConnectionHandler(this, socket)
    synchronized (lock) {
        clients.add(client);
    }
    new Thread(client).start();
    
  • Теперь нам просто нужен метод для распределения всех входящих сообщений на сервере. класс:

    void distributeMessage(String message) {
        List<ConnectionHandler> clientsCopy;
        synchronized (lock) {
            clientsCopy = new ArrayList<>(clients);
        }
        for (ConnectionHandler client : clientsCopy) {
            client.sendMessage(message);
        }
    }
    
  • Теперь нам нужно изменить ConnectionHandler, и мы начнем с очистки полей:

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

    Это все поля, которые мынужно.

  • Далее нам нужно изменить конструктор этого класса:

    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()));
    }
    

    Все поля должны быть инициализированы в конструкторе, если это возможно.

  • Затем мы должны добавить наш новый метод 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();
        }
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...