java - Java:TCP Socket 数据丢失
问题描述
我正在尝试为我的游戏创建一个服务器(当然还有一个客户端)。它是用 Java 开发的,没有额外的库或外部工作。当前设置了客户端和服务器连接,它将定义的字节数(512)作为“包”发送。每个包都有一个用于其类型的 ID(1 个字节)和一个用于其数据的主体(511 个字节)。一般来说,这种联系似乎有效。我目前面临的问题是,当我尽可能快地发送大量数据(地图 ~ 10kb ~ 1300 包)时,我似乎丢失了消息或接收到错误的消息(例如:错误的包 ID )。我似乎无法弄清楚为什么会这样。据我了解,Java 中的套接字使用 TCP 协议,据我所知,这应该可以防止这些问题。
这是服务器的重要(在我看来)部分:
void sendToClient(Queue<DataPackage> packages) {
if(isConnected()){
try {
while(!packages.isEmpty()){
this.out.write(packages.get().getByteData());
packages.remove();
this.out.flush();
}
} catch (IOException e) {
e.printStackTrace();
if(!isConnected()){
if(!ended){
ended = true;
server.getServerManager().getEventManager().publishServerEvent(new ServerLostConnectionToClientEvent(id, connection));
}
}
}
}
}
这是客户的重要(在我看来)部分:
private void acceptData() throws UnsupportedPackageException {
byte[] income = new byte[DataPackage.MAXPACKAGELENGTH];
try {
for(int length = in.read(income); length!=-1 && isConnected(); length = in.read(income)){
income = Arrays.copyOf(income, DataPackage.MAXPACKAGELENGTH);
DataPackage dataPackage = null;
try {
dataPackage = new DataPackage(income, length);
} catch (Exception ea) {ea.printStackTrace();}
if(dataPackage!=null){
if(!this.dataStreams.containsKey(dataPackage.getId())) this.dataStreams.put(dataPackage.getId(), new Queue<DataPackage>());
Queue<DataPackage> dataStream = dataStreams.get(dataPackage.getId());
if(dataPackage.isEnd()) {
this.dataStreams.remove(dataPackage.getId());
handNewDataPackage(dataPackage, dataStream);
}
}
income = new byte[DataPackage.MAXPACKAGELENGTH];
}
} catch (IOException e) {
e.printStackTrace();
if(this.client.run() && !ended){
this.client.endClient();
this.client.connectionLost(new ClientLostConnectionToServerEvent(this.socket));
}
ended = true;
}
}
这就是我设置连接的方式:
socket = new Socket(ip, port);
socket.setTcpNoDelay(false);
socket.setReceiveBufferSize(DataPackage.MAXPACKAGELENGTH);
socket.setSendBufferSize(DataPackage.MAXPACKAGELENGTH);
this.out = new BufferedOutputStream(socket.getOutputStream(), DataPackage.MAXPACKAGELENGTH);
this.in = new BufferedInputStream(socket.getInputStream(), DataPackage.MAXPACKAGELENGTH);
您可以在此处查看整个项目(如果需要):https ://github.com/reschiram/Game (最新分支:G-9)
如果这看起来只是关于如何编写 Java 套接字的另一个重复问题,我很抱歉。我也在这里看到了几个类似的问题,但似乎没有一个完全适合我的问题(或帮助我解决它)。
解决方案
推荐阅读
- css - 反应可折叠面板css问题
- javascript - JavaScript 中的变量超过 1 个 URL
- r - R中具有空间自相关的GAMM
- c# - SqlException Timeout 过期进入 Dot net core 2.2
- python - 如何从 Python 打开 Visual Studio 代码?
- javascript - 单击按钮清除选择框
- sql-server - 如何将可执行的sql任务结果存储在excel文件ssis中
- c# - 在 VS2017 中更改以下 Resharper 项目的颜色
- wildfly - Wildfly 错误:错误 MEM 发送 ENABLE-APP
- c# - 如何使文本框的宽度像 xaml 中的按钮一样动态变化