0

複数のクライアントを1つのサーバーに接続するという概念を完全に理解しているとは思いません。私はそれが非常に多くの異なる方法で行われるのを見てきました.

私が理解していることから、ServerSocket がクライアント ソケットから接続を取得するたびに、新しい Socket が作成されるため、リッスンし続けることができます。

人々がそれをコード (サーバー側) で記述しているのを見ると、常に 1 つのソケットを使用します。それ以来、私はそのようにしていますが、まだ進歩していません。

私の友人は、サーバーで動作するクライアントを作成しましたが、サーバーにメッセージをグローバルに表示させるには問題があります。これは私がそれをどのように構成したかです (最初の 3 つはサーバー用で、最後の 1 つはクライアント用です:

サーバー.java

package Main;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import Streams.Stream;

public class Server {

    public static final int maxConnections = 10;

    ServerSocket serverSocket;
    Socket socket;

    User[] users = new User[maxConnections];

    public Server() {
        try {
            serverSocket = new ServerSocket(43594);

            while(Stream.streams < maxConnections) {
                socket = serverSocket.accept();

                for(User user : users) {
                    if(user == null) {
                        user = new User(socket);

                        Thread t = new Thread(user);
                        t.start();
                        System.out.println("Someone has joined the chat!");
                        return;
                    }
                }

            }


        }catch(IOException e) { e.printStackTrace(); }
    }

    public static void main(String[] args) {
        new Server();
    }
}

ユーザー.java

package Main;

import java.io.IOException;
import java.net.Socket;

import Streams.Stream;

public class User implements Runnable {

    Stream stream;

    public User(Socket socket) {
        stream = new Stream(socket);

    }

    public void run() {
        String textInput, textOutput;

        while(stream.exists()) {
            try{
                textInput = (String) stream.recieveData();
            }catch(IOException  e) {
                e.printStackTrace();
            }catch(ClassNotFoundException e) { e.printStackTrace(); }
        }

    }

    public void sendMessage(String message) throws IOException {
        stream.sendData(message);
    }

}

ストリーム.java

package Streams;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class Stream {
    public static int streams = 0;

    Socket socket;

    ObjectInputStream input; ObjectOutputStream output;
    Object data;

    public Stream(Socket userSocket) {
        streams++;
        socket = userSocket;

        try{
            input = new ObjectInputStream(userSocket.getInputStream());
            output = new ObjectOutputStream(userSocket.getOutputStream());
        }catch(IOException e) { e.printStackTrace(); }

    }

    public void sendData(Object data) throws IOException {
        output.writeObject(data);
        output.flush();
    }

    public Object recieveData() throws IOException, ClassNotFoundException {
        return data = input.readObject();
    }


    public boolean exists() {
        if(socket.isClosed()) return false; else return true;
    }

}

クライアント.java

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Client extends JFrame {

    private JTextField userText;
    private JTextArea chatWindow;
    private ObjectOutputStream out;
    private ObjectInputStream in;
    private String message = "";
    private String serverIP;
    private Socket clientSocket;
    private int port = 43594;
    Boolean CNC = false;

    //constructor
    public Client(String serverIP) {
        super("Client Chat");

        this.serverIP = serverIP;

        userText = new JTextField();
        userText.setEditable(false);
        userText.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e) {
                    if(userText.getText().length() > 0) {
                        sendMessageToServer(userText.getText());
                        userText.setText("");
                    }
                }
            }
        );
        add(new ClientMenu(), BorderLayout.NORTH);
        add(userText, BorderLayout.SOUTH);
        chatWindow = new JTextArea();
        chatWindow.setEditable(false);
        add(new JScrollPane(chatWindow), BorderLayout.CENTER);
        add(new JScrollPane(new ClientTable()), BorderLayout.EAST);
        setSize(600, 300);
        setVisible(true);
    }

    //connect to server
    public void startRunning() {
        try{
            connectToServer();
            setupStreams();
            whileChatting();
        } catch(EOFException eofException) {
            showMessage("\n Client terminated the connetion");
        }catch(IOException ioException) {
            ioException.printStackTrace();
        }finally{
            closeCrap();
        }
    }

    //connect to server
    private void connectToServer() {
        showMessage("Attempting to connect to server... \n");
        try {
            clientSocket = new Socket(serverIP, port);
        } catch (UnknownHostException e) {
            CNC = true;
            e.printStackTrace();
        } catch (IOException e) {
            CNC = true;
            e.printStackTrace();
        }
        //showMessage("Connected to:" + connection.getInetAddress().getHostName());
    }

    //setup streams to send and receive messages
    private void setupStreams() {
        try {
            out = new ObjectOutputStream(clientSocket.getOutputStream());
            out.flush();
            in = new ObjectInputStream(clientSocket.getInputStream());
            showMessage("Stream established! \n");
            showMessage("Use ::setname to change your name \n");
        }catch(IOException e) { e.printStackTrace(); }

    }

    //while chatting with server
    private void whileChatting() throws IOException{
        ableToType(true);
        do{
            try{
                message = (String) in.readObject();

                showMessage("\n" + message);
            }catch(ClassNotFoundException classNotfoundException) {
                showMessage("\n ERROR! Message cannot be read");
            }
        }while(!message.equals("SERVER - END"));
    }

    //close the streams and sockets
    private void closeCrap(){
        if(CNC) {
            showMessage("ERROR! Could not connect to server");
        } else {
        showMessage("\n Ending connections...");
        ableToType(false);
        try{
            out.close();
            in.close();
            clientSocket.close();
        }catch(IOException ioException) {
            ioException.printStackTrace();
        }
      }
    }

    private void sendMessageToServer(String message) {
        try{
            out.writeObject(message);
            out.flush();
        }catch(IOException ioException) {
            chatWindow.append("\n ERROR! Could not send message!");
        }
    }

    //change/update chatWindow
    private void showMessage(final String message) {
        SwingUtilities.invokeLater(
                new Runnable() {
                    public void run() {
                        chatWindow.append(message);
                    }
                }
            );
    }

    //gives user permission to enter messages into text box
    private void ableToType(final boolean tof) {
        SwingUtilities.invokeLater(
                new Runnable() {
                    public void run() {
                        userText.setEditable(tof);
                    }
                }
            );
    }

    public static void main(String[] args) {
        Client c = new Client("thisisatestip.zapto.org");
        c.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        c.setLocationRelativeTo(null);
        c.startRunning();
    }
}

ServerSocket を静的にする代わりに、次のように User のコンストラクターを呼び出すことを考えていました

User(new Socket())

User クラスで接続を受け入れます。私にお知らせください

4

1 に答える 1