Files
min-dev-java/src/main/java/logicface/UdpTransport.java
T
2021-04-26 18:59:08 +08:00

125 lines
3.8 KiB
Java

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());
}
}
}