0

我要做的是从客户端->服务器发送一条消息,然后发送回连接到服务器的所有其他客户端(多线程)。从不同的客户端发送到服务器工作正常,但是当我尝试将其发送回来时,什么也没有发生。

每次有人连接时,它都会在我的 User[] 数组中创建一个新对象。有了它,我可以为每个用户触发输出流(User 中有一个 Stream 对象,其中包含输入和输出流,因此每次创建一个新的 User 对象时,也会创建一个新流)。

有了这个,我试图将传入的消息发送回我的用户数组中的每个其他用户(不 == null)。

问题是,当我回到发送消息的部分时,我的 User[] 数组中的所有用户都返回为“null”。

服务器.java:

package Main;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ForkJoinPool;

import Streams.Stream;

public class Server {
    public static final int maxConnections = 10;

    ServerSocket serverSocket; Socket socket;
    ForkJoinPool pool = new ForkJoinPool();

    static 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);
                        System.out.println(user +", 1");
                        pool.execute(user);
                        System.out.println("Someone has joined the chat!");
                        break;
                    } else {
                        System.out.println("Connection declined. Too many users.");
                        break;
                    }
                }
            }           
        }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();
                sendGlobalMessage(textInput);

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

        stream.close();
    }

    public void sendMessage(String message) throws IOException {
        stream.sendData(message);
    }
    public void sendGlobalMessage(String message) throws IOException {
        for(User user : Server.users) {
            if(user == null) {
                System.out.println(message);
            }else{
                user.sendMessage(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;
    }

    public void close() {
        try {
            input.close();
            output.close();
            socket.close();
        }catch(IOException e) { e.printStackTrace(); }
    }

}

我不确定它是否与我的服务器的结构有关。对我来说看起来很不错,我真的不知道为什么会这样做。

4

2 回答 2

4

您在此处的User引用是数组中引用的副本,而不是实际引用。

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

相当于

 User user = user[i];

更改引用user不会修改引用user[i]

您需要使用索引 for 循环来初始化(或重新引用)数组的元素

for (int i = 0; i <users.lenght; i++) {
    if(users[i] == null) {
        users[i] = new User(socket);
    } ...
    ...
}
于 2013-09-07T19:18:16.153 回答
2

您不能使用 for-each 循环初始化列表或数组中的项目。相反,您应该使用标准 for 循环。使用 for-each 循环,您将对象分配给一个临时变量,这对 List 项本身没有影响。

于 2013-09-07T19:17:08.193 回答