複数のクライアントを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 クラスで接続を受け入れます。私にお知らせください