Java TCP Socket实现Go Back N ARQ协议出现数组越界错误求助
问题原因
- 核心触发原因是客户端发送帧的循环逻辑未校验data数组边界:你编写的发送循环
for(int i=strt;i<x;i++)中,x是GBN协议的窗口大小(值为2^m -1),完全没有和count(用户输入的待发送总帧数,也就是data数组的长度)做边界限制。当窗口大小x大于count,或是重传时strt + x大于count时,循环变量i会超过data数组的最大索引count-1,访问data[i]时就会触发数组越界异常。 - 附带逻辑缺陷:当前的发送终止判断逻辑
listener.reply!=x-1错误使用窗口大小作为发送完成的判定依据,当待发送帧数count大于窗口大小x时,会出现未发送完所有帧就提前终止的问题。
解决方法
按以下步骤修改客户端代码即可修复问题:
- 替换发送帧的循环条件,增加数组边界校验
将原有代码:
for(int i=strt;i<x;i++)
修改为:
// 每次最多发送一个窗口的帧,且不超过待发送的总帧数,避免数组越界 for(int i = strt; i < Math.min(strt + x, count); i++)
- 修改发送终止判断逻辑,用总帧数作为判定依据
将原有代码:
if(listener.reply!=x-1) { System.out.println("No reply from server in 3.5 seconds. Resending data from frame no " + (listener.reply+1)); System.out.println(); strt=listener.reply+1; flag=false; } else { System.out.println("All elements sent successfully. Exiting"); flag=true; }
修改为:
// 确认收到最后一帧的应答才算全部发送完成 if(listener.reply < count -1) { System.out.println("No reply from server in 3.5 seconds. Resending data from frame no " + (listener.reply+1)); System.out.println(); strt=listener.reply+1; flag=false; } else { System.out.println("All elements sent successfully. Exiting"); flag=true; }
- 修复上下游同步阻塞问题(可选,避免连接后无响应)
服务端启动后会依次读取3个初始值:x、k、i,但客户端目前只写入了x,会导致首次连接阻塞,可在客户端oos.writeObject(x);之后补充两行初始值写入:
oos.writeObject(0); oos.writeObject(data[0]);
内容的提问来源于stack exchange,提问作者Siddha Mehta
相关产品推荐
相关产品推荐

