beykery / jkcp

kcp for java . 适用于moba,视频加速等需要极速传输场景的应用,c#版本(客户端)请参考:https://github.com/beykery/kcp4sharp
Apache License 2.0
186 stars 85 forks source link

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

Closed tidus5 closed 6 years ago

tidus5 commented 6 years ago

下面是日志。收到客户端准备完成的消息,就给两个客户端都发送战斗开始。 但是会出现有消息取不到数据,提示 消息已经被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]

tidus5 commented 6 years ago

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

beykery commented 6 years ago

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