Java 客户端-服务器编程:客户端之间的共享内存
Java Client-Server Programming: Shared Memory Between Clients
我正在 Java 开发一个简单的 2D 多人游戏,遵循客户端-服务器模型。套接字编程方面的功能很简单:
- 客户端向服务器发送他们的角色数据(x 位置、y 位置、生命值等)
- 服务器将更新后的角色数据注册到一个table中,该文件存储了所有不同客户端的角色数据
- 服务器将 table 发送回客户端,以便他们可以呈现其他字符
我 运行 遇到了一个奇怪的问题,我想帮助理解这个问题,以便我可以继续进行该项目。这是我现在 运行 的代码。
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());
这将使服务器按预期使用来自客户端的线路,并允许您查看/验证数据流。
我正在 Java 开发一个简单的 2D 多人游戏,遵循客户端-服务器模型。套接字编程方面的功能很简单:
- 客户端向服务器发送他们的角色数据(x 位置、y 位置、生命值等)
- 服务器将更新后的角色数据注册到一个table中,该文件存储了所有不同客户端的角色数据
- 服务器将 table 发送回客户端,以便他们可以呈现其他字符
我 运行 遇到了一个奇怪的问题,我想帮助理解这个问题,以便我可以继续进行该项目。这是我现在 运行 的代码。
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());
这将使服务器按预期使用来自客户端的线路,并允许您查看/验证数据流。