beykery/jkcp

给两个连接推送消息的时候,可能消息被release,导致发送失败

tidus5 opened this issue · 2 comments

下面是日志。收到客户端准备完成的消息,就给两个客户端都发送战斗开始。
但是会出现有消息取不到数据,提示 消息已经被free 的情况。
下面 add send bb 打印是在 KcpOnUdp 的send方法

public synchronized void send(ByteBuf bb)
{
if (!closed)
{
this.sendList.add(bb);
System.err.println("add send bb:"+ Thread.currentThread().getName()+" hash:"+bb.hashCode()+" bb:"+bb+" ref:"+bb.refCnt());
this.needUpdate = true;
}
}

send fail 是在 Kcp 的send 方法

public int send(ByteBuf buffer) {
System.err.println(" sending buffer :" +Thread.currentThread().getName()+" hash:"+ buffer.hashCode() + " buffer:" + buffer+" ref:"+buffer.refCnt());
if (buffer.readableBytes() == 0) {
System.err.println(" send fail, buffer :" + Thread.currentThread().getName()+" hash:" + buffer.hashCode() + " buffer:" + buffer+ " ref:"+buffer.refCnt());
return -1;
}

下面是出错日志:

2018-06-27 14:45:38][kcp thread 0] INFO - at com.test.fightserver.room.Room.clientReady(Room.java:60) -[ kcp ready:local: /0.0.0.0:2222 remote: /192.168.1.105:60305]
2018-06-27 14:45:38][kcp thread 0] INFO - at com.test.fightserver.room.Room.clientReady(Room.java:74) -[ all ready ]
2018-06-27 14:45:38][kcp thread 0] INFO - at com.test.fightserver.room.Room.clientReady(Room.java:90) -[ send player enter to local: /0.0.0.0:2222 remote: /192.168.1.103:60354 msg: UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 30, cap: 30) readableBytes :30]
2018-06-27 14:45:38][kcp thread 0] INFO - at com.test.fightserver.room.Room.clientReady(Room.java:90) -[ send player enter to local: /0.0.0.0:2222 remote: /192.168.1.105:60305 msg: UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 30, cap: 30) readableBytes :30]
2018-06-27 14:45:38][kcp thread 0] INFO - at com.test.fightserver.room.Room.clientReady(Room.java:118) -[ send battle start to local: /0.0.0.0:2222 remote: /192.168.1.103:60354 msg: UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 12, cap: 12) readableBytes :12]
2018-06-27 14:45:38][kcp thread 0] INFO - at com.test.fightserver.room.Room.clientReady(Room.java:118) -[ send battle start to local: /0.0.0.0:2222 remote: /192.168.1.105:60305 msg: UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 12, cap: 12) readableBytes :12]
add send bb:kcp thread 0 hash:1304880682 bb:UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 12, cap: 12) ref:1
sending buffer :kcp thread 0 hash:1128752854 buffer:UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 30, cap: 30) ref:1
sending buffer :kcp thread 0 hash:1304880682 buffer:UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 12, cap: 12) ref:1
sending buffer :kcp thread 0 hash:1128752854 buffer:UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 30, cap: 30) ref:1
sending buffer :kcp thread 0 hash:1304880682 buffer:UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 12, cap: 12) ref:1
add send bb:pool-3-thread-1 hash:-168963106 bb:UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 16, cap: 16) ref:1
add send bb:pool-3-thread-1 hash:-168963106 bb:UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 16, cap: 16) ref:1
2018-06-27 14:45:38][kcp thread 0] INFO - at com.test.fightserver.server.UdpServer.handleReceive(UdpServer.java:48) -[ client msg:3012 kcp:local: /0.0.0.0:2222 remote: /192.168.1.103:60354]
sending buffer :kcp thread 0 hash:-168963106 buffer:UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 16, cap: 16) ref:1
sending buffer :kcp thread 0 hash:1 buffer:UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(freed) ref:0
send fail, buffer :kcp thread 0 hash:1 buffer:UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(freed) ref:0
2018-06-27 14:45:38][kcp thread 0] ERROR - at com.test.fightserver.server.UdpServer.handleException(UdpServer.java:62) -[ ]
java.lang.IllegalStateException: send error : -1
at org.beykery.jkcp.KcpOnUdp.update(KcpOnUdp.java:198) [classes/:?]
at org.beykery.jkcp.KcpThread.run(KcpThread.java:154) [classes/:?]
2018-06-27 14:45:38][kcp thread 0] INFO - at com.test.fightserver.server.UdpServer.handleClose(UdpServer.java:68) -[ client close................local: /0.0.0.0:2222 remote: /192.168.1.105:60305]

找到问题了,本以为是多线程的问题。后来感觉在其他线程 调用 KcpOnUdp.send() 应该还好。
问题是 有个消息为了测试重复发送,对 发送的 ByteBuf 进行了缓存和多次 send。
如果不是在一次flush 里,那么发送成功后,导致 ByteBuf 被release, 后面发送就取到空的 ByteBuf了

send以后,buffer就空了。而且被release。