Java 客户端-服务器编程:客户端之间的共享内存

Java Client-Server Programming: Shared Memory Between Clients

我正在 Java 开发一个简单的 2D 多人游戏,遵循客户端-服务器模型。套接字编程方面的功能很简单:

我 运行 遇到了一个奇怪的问题,我想帮助理解这个问题,以便我可以继续进行该项目。这是我现在 运行 的代码。

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Set;
import java.util.Vector;
import java.util.HashSet;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server
{

    private static Vector<Integer> IDs = new Vector<>();

    public static void main(String[] args) throws Exception
    {
        ExecutorService pool = Executors.newFixedThreadPool(32);

        try (ServerSocket listener = new ServerSocket(40000)) 
        {
            System.out.println("The server is up.");
            while (true)
            {
                pool.execute(new Player(listener.accept()));
            }
        }
    }

    private static class Player implements Runnable
    {
        private Socket socket;
        private Scanner input;
        private PrintWriter output;
        private int ID;

        public Player(Socket socket)
        {
            this.socket = socket;
            this.ID = IDs.size() + 1;
            IDs.add(ID);
        }

        public void run()
        {
            try
            {
                input = new Scanner(socket.getInputStream());
                output = new PrintWriter(socket.getOutputStream(), true);

                while(input.hasNextLine())
                {
                    String result = "";
                    for(int i = 0; i < IDs.size(); i++)
                    {
                        result += (IDs.get(i) + " ");
                    }
                    output.println(result);
                }
            }
            catch(Exception e)
            {
                System.out.println(e);
            }
        }
    }
}
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws Exception {
        try (Socket socket = new Socket("127.0.0.1", 40000)) {
            Scanner scanner = new Scanner(System.in);
            Scanner in = new Scanner(socket.getInputStream());
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            while (scanner.hasNextLine()) {
                out.println(scanner.nextLine());
                System.out.println(in.nextLine());
            }
            in.close();
            scanner.close();
        }
    }
}

我想要发生的是:每次客户端向服务器发送任何消息时,服务器都会返回一个 ID 列表(每个连接的客户端都会获得一个新的 ID)。

实际发生了什么:

第二个连接的客户端能够看到已经连接的第一个客户端。但是第一个客户端无法看到有第二个客户端连接。

感谢您的帮助。

服务器循环

while(input.hasNextLine())
{
    String result = "";
    for(int i = 0; i < IDs.size(); i++)
    {
        result += (IDs.get(i) + " ");
    }
    output.println(result);
}

从不调用 input.nextLine(),这意味着 input.hasNextLine() 始终为真,因此服务器用输出淹没套接字,直到缓冲区已满。

这可以通过启动客户端,关闭服务器,然后一直按回车键来查看。客户端一直在接收数据,即使服务器不在了,直到缓冲区被清空。

在循环内添加以下行:

System.out.println(this.ID + ": " + input.nextLine());

这将使服务器按预期使用来自客户端的线路,并允许您查看/验证数据流。