gpt4 book ai didi

java - 为什么我的数据报套接字停止接收数据,即使它接收的数据完全正常?

转载 作者:行者123 更新时间:2023-12-01 14:24:56 25 4
gpt4 key购买 nike

我正在用 java 制作多人游戏,但我确实遇到了一些问题。由于某种原因,我的数据报套接字将停止接收从客户端设置的数据包,即使根据控制台,它之前收到的数据包很好。我对网络或套接字编程不太了解,所以这让我很困惑。

这是我的代码:

服务器:

package server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;

import shared.BaseEntity;
import shared.MethodNotOverridenException;
import shared.Packet;
import shared.Player;

public class S_GameLoop implements Runnable{
//Constants
private static final int TICKS_PER_SECOND = 25;
private static final int TICKS_TO_SKIP = 1000 / TICKS_PER_SECOND;
private static final int MAX_FRAMESKIP = 5;
private static final int SPAWN_COORD_X = 50;
private static final int SPAWN_COORD_Y = 50;

private Vector<S_Client> ClientList;
private Map<Integer, BaseEntity> EntityMap;
private AtomicInteger IDGenerator;

private boolean gameIsRunning = true;
private DatagramSocket socket;
byte[] recieveData = new byte[1024];
byte[] prevRecieveData = new byte[1024];

private int port;
private int loops;

public S_GameLoop(int port) {
ClientList = new Vector<S_Client>();
this.port = port;
IDGenerator = new AtomicInteger();
EntityMap = new HashMap<Integer, BaseEntity>();
}

private void Init() throws SocketException {
System.out.println("INIT");
socket = new DatagramSocket(port);
System.out.println("[Server] Create listen server on " + socket.getLocalAddress().getHostAddress() + " on port " + socket.getLocalPort());
socket.setSoTimeout(0);
}

private void Running() {
System.out.println("S_GameLoop staring");
long nextGameTick = System.currentTimeMillis();

DatagramPacket recievePacket = new DatagramPacket(recieveData, recieveData.length);

//GameLoop goes here
while(gameIsRunning) {
loops = 0;

//Receive the data
try {
socket.receive(recievePacket);
} catch (IOException e1) {
e1.printStackTrace();
}

while(System.currentTimeMillis() > nextGameTick && loops < MAX_FRAMESKIP) {
try {
Update(recievePacket);
} catch (MethodNotOverridenException | IOException e) {
System.err.println(e);
}

nextGameTick += TICKS_TO_SKIP;
loops++;
}

nextGameTick += TICKS_TO_SKIP;
loops++;

try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

private void Update(DatagramPacket recievePacket) throws IOException, MethodNotOverridenException {
if(prevRecieveData != recieveData) {
parseData(formatData(recievePacket.getData()), recievePacket);
prevRecieveData = recieveData;
} else {
return;
}
}

public static Packet formatData(byte[] data) {
try {
if(data[1] == 0);
String tag = new String(Arrays.copyOfRange(data, 1, 8));
System.out.println("[Server] Recieved packet " + data[0] + " " + new String(tag));
return new Packet(data[0],tag.getBytes(), Arrays.copyOfRange(data, 8, data.length));
} catch (ArrayIndexOutOfBoundsException e) {
return new Packet((byte)0, new byte[0], new byte[0]);
}
}

private void parseData(Packet p, DatagramPacket recievePacket) throws IOException, MethodNotOverridenException {
if(p.getTag() == new byte[0]) {
System.out.println("[Server] Recieved NULL packet");
return;
}
switch (p.getTagAsString()) {
case "LGN_RQS": System.out.println("[Server] Login Request Recieved");
//Login was accepted
//Create a Client ref, and add it to the vector
S_Client newClient = new S_Client(recievePacket.getAddress(), recievePacket.getPort());
ClientList.add(newClient);

//Create a player and add it to Entity list
Player newPlayer = new Player(IDGenerator.getAndIncrement(), ClientList.indexOf(newClient));
EntityMap.put(newPlayer.getEntID(), newPlayer);
System.out.println("[Server] Created new Player with EID " + newPlayer.getEntID() + " and CID " + newPlayer.getCID());
//Send reply to Client that is logging in
sendData(new Packet((byte)2, "LGN_ACP".getBytes(), ("CID;" + ClientList.indexOf(newClient) + ";EID;" + newPlayer.getEntID()).getBytes()).getBytes(), newClient.getIp(), newClient.getPort());
//New Entity was created
//sendData(newPlayer.onCreate(this));
break;

case "HND_SHK": System.out.println("[Server] Handshake Recieved");

String fdata = new String(p.getData());
String[] data = fdata.split(";");

//Get client by client ID
S_Client c = ClientList.get(Integer.parseInt(data[1]));
c.setUsername(data[3]);
System.out.println("[Server] Set Client " + data[1] + "'s username to " + data[3]);
//Now spawn the player
sendData(new Packet((byte)9, "PLR_SPW".getBytes(), ("CID;" + data[1] + ";X;" + SPAWN_COORD_X + ";Y;" + SPAWN_COORD_Y).getBytes()).getBytes());
break;
}
}

public String[] byteArrayToStringArray(byte[] b) {
String fdata = new String(b);
return fdata.split(";");
}

public void createEntity(BaseEntity be) throws MethodNotOverridenException, IOException {
int ID = IDGenerator.incrementAndGet();
be.setEntID(ID);
EntityMap.put(ID, be);
sendData(be.onCreate(this));
}

public void sendData(byte[] sendData, InetAddress IP, int port) throws IOException {
System.out.println("[Server] Send packet " + sendData[0] + " " + new String(Arrays.copyOfRange(sendData, 1, 8)));
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IP, port);
socket.send(sendPacket);
}

public void sendData(byte[] sendData) throws IOException {
for (S_Client entry : ClientList) {
sendData(sendData, entry.getIp(), entry.getPort());
}
}

@Override
public void run() {
try {
Init();
Running();
} catch (SocketException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
}
}

客户:

package client;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.Arrays;
import java.util.Vector;

import shared.BaseEntity;
import shared.Packet;
import shared.Player;

public class C_GameLoop {
//How fast should the game update?
private static final int TICKS_PER_SECOND = 25;
//How many ticks should be skipped in order to run it at that speed?
//If it runs faster, then the Render() will be called more often
private static final int TICKS_TO_SKIP = 1000 / TICKS_PER_SECOND;
//How many times should you skip rendering, if you have to?
private static final int MAX_FRAMESKIP = 5;

RenderCanvas rc;

InetAddress ServerIP;
private DatagramSocket socket;
private int port;
private boolean connectedToServer = false;
private boolean waitForData = false;
private String username = "Dummy";
byte[] sendPacket;

Vector<BaseEntity> RenderList;
Player player;


int fps = 0;

public C_GameLoop(RenderCanvas rc){
this.rc = rc;
RenderList = new Vector<BaseEntity>();
}


public boolean Connect(InetAddress ServerIP, int port) throws IOException {
this.port = port;
this.ServerIP = ServerIP;
socket = new DatagramSocket();
socket.setSoTimeout(4000);

DatagramPacket recieveData = new DatagramPacket(new byte[1024], new byte[1024].length);

System.out.println("[Client] Connecting to: " + ServerIP.getHostAddress() + ":" + port);
//Send a login request
sendData(new Packet((byte)1, "LGN_RQS".getBytes()).getBytes());
int retries = 0;

//Start the connect loop
while(!connectedToServer) {
try {
socket.receive(recieveData);
waitForData = false;
parseData(formatData(recieveData.getData()));
//recieveData.setData(new Packet((byte)0, new byte[0], new byte[0]).getBytes());
} catch (SocketTimeoutException e) {
if(waitForData = true && retries <= 4) {
System.out.println("[Client] Failed to recieve response from server, retrying");
parseData(formatData(recieveData.getData()));
retries++;
} else {
System.out.println("[Client] Failed to Connect to the server!");
return false;
}
} catch (IOException e) {
e.printStackTrace();
}
}

return true;
}

public void sendData(byte[] data) throws IOException {
System.out.println("[Client] Sent packet " + data[0] + " " + new String(Arrays.copyOfRange(data, 1, 8)));
DatagramPacket sendPacket = new DatagramPacket(data, data.length, ServerIP, port);
socket.send(sendPacket);
waitForData = true;
}

private void parseData(Packet p) throws IOException {
switch (p.getTagAsString()) {
case "LGN_ACP": System.out.println("[Client] Login Accepted");
//Get the data needed to create a new player from the packet
String fdata = new String(p.getData());
String[] data = fdata.split(";");
Player player = new Player(Integer.parseInt(data[1]), Integer.parseInt(data[3].trim()));
//Add it to the render list
this.player = player;
rc.getCamera().addDrawableEntity(player);

System.out.println("[Client] Player created with CID " + data[1] + " and EID " + data[3]);

//Send the handshake
System.out.println("[Client] Finshing Handshake...");
sendData(new Packet((byte)4, "HND_SHK".getBytes(), ("CID;" + player.getCID() + ";Username;" + username).getBytes()).getBytes());
break;
case "PLR_SPW": System.out.println("[Client] Spawn Recieved");
//Get the coords
String[] spawn_data = byteArrayToStringArray(p.getData());
this.player.setX(Integer.parseInt(spawn_data[3]));
this.player.setY(Integer.parseInt(spawn_data[5].trim()));

sendData(new Packet((byte)0, "KEP_ALV".getBytes()).getBytes());
break;

}
}

public String[] byteArrayToStringArray(byte[] b) {
String fdata = new String(b);
return fdata.split(";");
}

/*
* Formats data into a packet
*/
public static Packet formatData(byte[] data) {
try {
if(data[1] == 0);
String tag = new String(Arrays.copyOfRange(data, 1, 8));
System.out.println("[Client] Recieved packet " + data[0] + " " + new String(tag));
return new Packet(data[0],tag.getBytes(), Arrays.copyOfRange(data, 8, data.length));
} catch (ArrayIndexOutOfBoundsException e) {
return new Packet((byte)0, new byte[0], new byte[0]);
}
}
}

运行代码时控制台输出:

 INIT
[Server] Create listen server on 0.0.0.0 on port 4334
S_GameLoop staring
[Client] Connecting to: 127.0.0.1:4334
[Client] Sent packet 1 LGN_RQS
[Server] Recieved packet 1 LGN_RQS
[Server] Login Request Recieved
[Server] Created new Player with EID 0 and CID 0
[Server] Send packet 2 LGN_ACP
[Client] Recieved packet 2 LGN_ACP
[Client] Login Accepted
[Client] Player created with CID 0 and EID 0
[Client] Finshing Handshake...
[Client] Sent packet 4 HND_SHK
[Client] Failed to recieve response from server, retrying
(Same lines as previous 6 just repeat 4 times)
[Client] Failed to Connect to the server!

有什么想法吗?

最佳答案

看起来您的 Server 类被设计为用作某些工作线程的 Runnable

我怀疑问题是 run() 方法由于未捕获的异常而终止,并且工作线程只是终止。

我建议您配置一个默认的未捕获异常处理程序来(至少)记录致命异常的堆栈跟踪。有关详细信息,请参阅Thread javadocs。

关于java - 为什么我的数据报套接字停止接收数据,即使它接收的数据完全正常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17227187/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com