Java Static NonStatic 问题 - 如何在不重新启动程序的情况下创建新实例
Java Static NonStatic issues - how to create a new instance without starting the program again
我正在 Java 中制作游戏代理,我已经完成了,但是我遇到了一个问题,客户端数据包似乎没有发送到服务器,反之亦然。
我已经发布了 4 classes:代理、客户端、服务器和发送。
代理 class 刚刚开始一切。
Client class 处理来自客户端的数据包
服务器 class 处理来自服务器的数据包
Send class 应该使用 Getters 将数据包发送到正确的 DataOutputStream。
我认为问题是因为我无法访问非静态 getters
我知道我必须使用它的一个实例,但是当您查看代码时,您会发现如果我创建一个新的服务器实例,例如:
Server serv = new Server(null);
这意味着将重新启动与远程服务器的连接,我不希望这样...
如果我为客户端执行此操作,则意味着 clientSocket 已重新启动 - 我也不希望这样。
我已经研究这个问题好几个小时了,我终于寻求帮助,看看能否解决这个问题。
代理 Class:
public class Proxy {
private static ServerSocket server;
private static int port = 9339;
private static String originalHost = "game.boombeachgame.com.";
public static void start() {
Log.init();
Log.logInfo("* Proxy started");
Proxy.startThreadServer();
}
public static void startThreadServer() {
try {
server = new ServerSocket(port);
Socket clientSocket = server.accept();
new Thread(new Server(originalHost)).start();
new Thread(new Client(clientSocket)).start();
} catch (Exception e) {
System.out.println(e);
}
}
}
客户Class:
public class Client implements Runnable {
private Socket socket;
private DataOutputStream os;
private DataInputStream is;
public Client(Socket clientSocket) throws IOException {
setSocket(clientSocket);
os = new DataOutputStream(getSocket().getOutputStream());
is = new DataInputStream(getSocket().getInputStream());
Log.logInfo("* Client connected....");
}
@Override
public void run() {
new Crypt();
try {
while (true) {
int type = is.readUnsignedShort();
int size = is.readUnsignedByte();
size <<= 8;
size |= is.readUnsignedByte();
size <<= 8;
size |= is.readUnsignedByte();
int fsize = size+7;
int version = is.readUnsignedShort();
byte array[] = new byte[7];
array[0] = (byte)((type >>> 8) & 0xFF);
array[1] = (byte)(type & 0xFF);
array[2] = (byte)((size >>> 16) & 0xFF);
array[3] = (byte)((size >>> 8) & 0xFF);
array[4] = (byte)(size & 0xFF);
array[5] = (byte)((version >>> 8) & 0xFF);
array[6] = (byte)(version & 0xFF);
final byte[] request = new byte[size];
is.readFully(request,0,size);
byte[] data = new byte[array.length + request.length];
System.arraycopy(array, 0, data, 0, array.length);
System.arraycopy(request, 0, data, array.length, request.length);
System.out.println("\n\nPacket From Client");
System.out.println("Type: " + type + "");
System.out.println("Full Length: " + fsize+ "");
System.out.println("Data Length: " + size + "");
System.out.println("Version: " + version + "");
System.out.println("Packet Data: " + DatatypeConverter.printHexBinary(Crypt.decrypt(request, type)) + "\n");
new Send(data,"Client");
}
} catch (Exception e) {
}
}
public DataOutputStream getOutputStream() {
return os;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
服务器Class:
public class Server implements Runnable {
private Socket socket;
private DataOutputStream os;
private DataInputStream is;
public Server(String originalHost) throws Exception {
setSocket(new Socket(originalHost, 9339));
os = new DataOutputStream(getSocket().getOutputStream());
is = new DataInputStream(getSocket().getInputStream());
Log.logInfo("* Connected to Boom Beach Server");
}
@Override
public void run() {
new Crypt();
try {
while (true) {
int type = is.readUnsignedShort();
int size = is.readUnsignedByte();
size <<= 8;
size |= is.readUnsignedByte();
size <<= 8;
size |= is.readUnsignedByte();
int fsize = size+7;
int version = is.readUnsignedShort();
byte array[] = new byte[7];
array[0] = (byte)((type >>> 8) & 0xFF);
array[1] = (byte)(type & 0xFF);
array[2] = (byte)((size >>> 16) & 0xFF);
array[3] = (byte)((size >>> 8) & 0xFF);
array[4] = (byte)(size & 0xFF);
array[5] = (byte)((version >>> 8) & 0xFF);
array[6] = (byte)(version & 0xFF);
byte[] reply = new byte[size];
is.readFully(reply,0,size);
byte[] data = new byte[array.length + reply.length];
System.arraycopy(array, 0, data, 0, array.length);
System.arraycopy(reply, 0, data, array.length, reply.length);
System.out.println("\n\nPacket From Server");
System.out.println("Type: " + type + "");
System.out.println("Full Length: " + fsize+ "");
System.out.println("Data Length: " + size + "");
System.out.println("Version: " + version + "");
System.out.println("Header: " + DatatypeConverter.printHexBinary(array) + "");
System.out.println("Packet Data: " + DatatypeConverter.printHexBinary(Crypt.decrypt(reply,type)) + "\n");
new Send(data,"Server");
}
} catch (Exception e) {
}
}
public DataOutputStream getOutputStream() {
return os;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
发送Class:
public class Send{
private Socket sock = null;
private DataOutputStream out;
public Send(byte[] data, String from) throws IOException {
if (from == "Client"){
sock = Server.getSocket();
out = new DataOutputStream(sock.getOutputStream());
}else{
sock = Client.getSocket();
out = new DataOutputStream(sock.getOutputStream());
}
out.write(data);
}
}
我知道不应该发布完整的代码,但我多年来一直在努力寻找修复方法。我知道我不能使 DataOutputStreams
静态化,所以我需要一种方法来访问它们而无需可用的替代实例。
seems that the client packets aren't getting sent to the server and vice versa
尝试
out.write(data);
out.flush();
如果您不想创建 Server
class 的多个实例,那么您可以创建 singleton。将 Server
的构造函数设为私有,这样您就无法从 Server
class.
之外的任何地方创建 Server
的实例
public class Server implements Runnable {
.......
private Server instance = null;
private Server(String originalHost) throws Exception {
setSocket(new Socket(originalHost, 9339));
os = new DataOutputStream(getSocket().getOutputStream());
is = new DataInputStream(getSocket().getInputStream());
Log.logInfo("* Connected to Boom Beach Server");
}
public static Server getInstance(String originalHost){
if(instance == null){
instance = new Server(originalHost);
}
return instance;
}
.........
}
无论您在何处创建 Server
的新实例,只需执行
Server instance = Server.getInstance(originalHost);
并且您保证每次都获得相同的实例(除非是多线程环境)。
我正在 Java 中制作游戏代理,我已经完成了,但是我遇到了一个问题,客户端数据包似乎没有发送到服务器,反之亦然。
我已经发布了 4 classes:代理、客户端、服务器和发送。
代理 class 刚刚开始一切。 Client class 处理来自客户端的数据包 服务器 class 处理来自服务器的数据包 Send class 应该使用 Getters 将数据包发送到正确的 DataOutputStream。
我认为问题是因为我无法访问非静态 getters
我知道我必须使用它的一个实例,但是当您查看代码时,您会发现如果我创建一个新的服务器实例,例如:
Server serv = new Server(null);
这意味着将重新启动与远程服务器的连接,我不希望这样...
如果我为客户端执行此操作,则意味着 clientSocket 已重新启动 - 我也不希望这样。
我已经研究这个问题好几个小时了,我终于寻求帮助,看看能否解决这个问题。
代理 Class:
public class Proxy {
private static ServerSocket server;
private static int port = 9339;
private static String originalHost = "game.boombeachgame.com.";
public static void start() {
Log.init();
Log.logInfo("* Proxy started");
Proxy.startThreadServer();
}
public static void startThreadServer() {
try {
server = new ServerSocket(port);
Socket clientSocket = server.accept();
new Thread(new Server(originalHost)).start();
new Thread(new Client(clientSocket)).start();
} catch (Exception e) {
System.out.println(e);
}
}
}
客户Class:
public class Client implements Runnable {
private Socket socket;
private DataOutputStream os;
private DataInputStream is;
public Client(Socket clientSocket) throws IOException {
setSocket(clientSocket);
os = new DataOutputStream(getSocket().getOutputStream());
is = new DataInputStream(getSocket().getInputStream());
Log.logInfo("* Client connected....");
}
@Override
public void run() {
new Crypt();
try {
while (true) {
int type = is.readUnsignedShort();
int size = is.readUnsignedByte();
size <<= 8;
size |= is.readUnsignedByte();
size <<= 8;
size |= is.readUnsignedByte();
int fsize = size+7;
int version = is.readUnsignedShort();
byte array[] = new byte[7];
array[0] = (byte)((type >>> 8) & 0xFF);
array[1] = (byte)(type & 0xFF);
array[2] = (byte)((size >>> 16) & 0xFF);
array[3] = (byte)((size >>> 8) & 0xFF);
array[4] = (byte)(size & 0xFF);
array[5] = (byte)((version >>> 8) & 0xFF);
array[6] = (byte)(version & 0xFF);
final byte[] request = new byte[size];
is.readFully(request,0,size);
byte[] data = new byte[array.length + request.length];
System.arraycopy(array, 0, data, 0, array.length);
System.arraycopy(request, 0, data, array.length, request.length);
System.out.println("\n\nPacket From Client");
System.out.println("Type: " + type + "");
System.out.println("Full Length: " + fsize+ "");
System.out.println("Data Length: " + size + "");
System.out.println("Version: " + version + "");
System.out.println("Packet Data: " + DatatypeConverter.printHexBinary(Crypt.decrypt(request, type)) + "\n");
new Send(data,"Client");
}
} catch (Exception e) {
}
}
public DataOutputStream getOutputStream() {
return os;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
服务器Class:
public class Server implements Runnable {
private Socket socket;
private DataOutputStream os;
private DataInputStream is;
public Server(String originalHost) throws Exception {
setSocket(new Socket(originalHost, 9339));
os = new DataOutputStream(getSocket().getOutputStream());
is = new DataInputStream(getSocket().getInputStream());
Log.logInfo("* Connected to Boom Beach Server");
}
@Override
public void run() {
new Crypt();
try {
while (true) {
int type = is.readUnsignedShort();
int size = is.readUnsignedByte();
size <<= 8;
size |= is.readUnsignedByte();
size <<= 8;
size |= is.readUnsignedByte();
int fsize = size+7;
int version = is.readUnsignedShort();
byte array[] = new byte[7];
array[0] = (byte)((type >>> 8) & 0xFF);
array[1] = (byte)(type & 0xFF);
array[2] = (byte)((size >>> 16) & 0xFF);
array[3] = (byte)((size >>> 8) & 0xFF);
array[4] = (byte)(size & 0xFF);
array[5] = (byte)((version >>> 8) & 0xFF);
array[6] = (byte)(version & 0xFF);
byte[] reply = new byte[size];
is.readFully(reply,0,size);
byte[] data = new byte[array.length + reply.length];
System.arraycopy(array, 0, data, 0, array.length);
System.arraycopy(reply, 0, data, array.length, reply.length);
System.out.println("\n\nPacket From Server");
System.out.println("Type: " + type + "");
System.out.println("Full Length: " + fsize+ "");
System.out.println("Data Length: " + size + "");
System.out.println("Version: " + version + "");
System.out.println("Header: " + DatatypeConverter.printHexBinary(array) + "");
System.out.println("Packet Data: " + DatatypeConverter.printHexBinary(Crypt.decrypt(reply,type)) + "\n");
new Send(data,"Server");
}
} catch (Exception e) {
}
}
public DataOutputStream getOutputStream() {
return os;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
发送Class:
public class Send{
private Socket sock = null;
private DataOutputStream out;
public Send(byte[] data, String from) throws IOException {
if (from == "Client"){
sock = Server.getSocket();
out = new DataOutputStream(sock.getOutputStream());
}else{
sock = Client.getSocket();
out = new DataOutputStream(sock.getOutputStream());
}
out.write(data);
}
}
我知道不应该发布完整的代码,但我多年来一直在努力寻找修复方法。我知道我不能使 DataOutputStreams
静态化,所以我需要一种方法来访问它们而无需可用的替代实例。
seems that the client packets aren't getting sent to the server and vice versa
尝试
out.write(data);
out.flush();
如果您不想创建 Server
class 的多个实例,那么您可以创建 singleton。将 Server
的构造函数设为私有,这样您就无法从 Server
class.
Server
的实例
public class Server implements Runnable {
.......
private Server instance = null;
private Server(String originalHost) throws Exception {
setSocket(new Socket(originalHost, 9339));
os = new DataOutputStream(getSocket().getOutputStream());
is = new DataInputStream(getSocket().getInputStream());
Log.logInfo("* Connected to Boom Beach Server");
}
public static Server getInstance(String originalHost){
if(instance == null){
instance = new Server(originalHost);
}
return instance;
}
.........
}
无论您在何处创建 Server
的新实例,只需执行
Server instance = Server.getInstance(originalHost);
并且您保证每次都获得相同的实例(除非是多线程环境)。