package logicface; import common.LoggerHelper; import packet.LpPacket; import java.net.*; import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.Channel; import java.nio.channels.DatagramChannel; import java.nio.channels.SocketChannel; import java.sql.Time; /* * @Author: Wang Feng * @Description: * @Version: 1.0.0 * @Date: 21:16 2021/4/15 * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ public class UdpTransport extends Transport implements ITransport{ // public DatagramSocket datagramSocket; // UDP句柄 (channel比socket性能更好) public DatagramChannel channel; // 接收缓冲区,大小为 9000 public byte[] recvBuf; // 对端UDP地址,用于发送UDP包 public SocketAddress remoteUdpAddr; /** * 用于接收数据的transport的初始化函数 * @param channel */ public void init(DatagramChannel channel,SocketAddress remoteUdpAddr) throws LogicFaceException { try { this.channel=channel; this.localAddr=channel.getLocalAddress().toString(); this.localUri="udp://"+this.localAddr; this.remoteAddr=remoteUdpAddr.toString(); this.remoteUri="udp://"+this.remoteAddr; this.recvBuf=new byte[9000]; this.remoteUdpAddr=remoteUdpAddr; } catch (IOException e) { throw new LogicFaceException("UdpTransport.init: "+e.getMessage()); } } /** * 关闭 */ @Override public void close() { try { this.channel.close(); } catch (IOException e) { LoggerHelper.logger.error(e.getMessage()); } } /** * 发送一个lpPacket * @param lpPacket * @return */ @Override public boolean send(LpPacket lpPacket) throws LogicFaceException { try { byte[] encodeBuf=this.encodeLpPacket2ByteArray(lpPacket); if(encodeBuf.length<=0){ return false; } LoggerHelper.logger.debug("start write to udp : "+this.remoteUdpAddr.toString()); this.channel.socket().connect(remoteUdpAddr); int res=this.channel.write(ByteBuffer.wrap(encodeBuf)); if(res<0){ return false; } return true; } catch (LogicFaceException | IOException e) { throw new LogicFaceException("UdpTransport.send: "+e.getMessage()); } } /** * 从UDP句柄中接收到UDP包,并返回给上层 * @return */ private LpPacket doReceive() throws LogicFaceException { try { SocketAddress remoteUdpAddr=this.channel.receive(ByteBuffer.wrap(this.recvBuf)); if(remoteUdpAddr==null){ return null; } LoggerHelper.logger.debug("recv from udp: "+this.remoteAddr); LpPacket lpPacket=this.parseByteArray2LpPacket(this.recvBuf); if(lpPacket==null){ return null; } return lpPacket; } catch (IOException e) { throw new LogicFaceException("UdpTransport.doReceive: "+e.getMessage()); } } @Override public LpPacket receive() throws LogicFaceException { return this.doReceive(); } @Override public boolean setReadTimeout(long duration) throws LogicFaceException { try { if (duration <= 0) { this.channel.socket().setSoTimeout(0); return true; } this.channel.socket().setSoTimeout((int)(duration)); return true; } catch (SocketException e) { throw new LogicFaceException("UdpTransport.setReadTimeout"+e.getMessage()); } } }