1.引用jar包
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.0.16</version>
</dependency>
2.编写服务端
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
/**
* Mina 框架 UDP服务端测试案例
* Created by Administrator on 2016-11-25.
*/
public class UDPTest {
private final static int UDPORT = 10006;
public static void main(String[] args) throws IOException {
// ** Acceptor设置
NioDatagramAcceptor acceptor = new NioDatagramAcceptor();
// 此行代码能让你的程序整体性能提升10倍
acceptor.getFilterChain()
.addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
设置MINA2的IoHandler实现类
acceptor.setHandler(new UdpServerHandler());
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
chain.addLast("logger", new LoggingFilter());
// 设置每一个非主监听连接的端口可以重用
acceptor.getSessionConfig().setReuseAddress(true);
// ** UDP服务端开始侦听
acceptor.bind(new InetSocketAddress(UDPORT));
System.out.println("udp服务端开始侦听");
}
}
3.业务端数据处理
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
/**
* UDP数据业务处理
* Created by Administrator on 2016-11-25.
*/
public class UdpServerHandler extends IoHandlerAdapter {
/**
* MINA的异常回调方法。 本类中将在异常发生时,立即close当前会话。
*
* @param session
* 发生异常的会话
* @param cause
* 异常内容
*/
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
cause.printStackTrace();
session.close(true);
}
/**
* MINA框架中收到客户端消息的回调方法。 本类将在此方法中实现完整的即时通讯数据交互和处理策略。
* 为了提升并发性能,本方法将运行在独立于MINA的IoProcessor之外的线程池中
*
* @param session
* 收到消息对应的会话引用
* @param message
* 收到的MINA的原始消息封装对象,本类中是 {@link IoBuffer}对象
* @throws Exception
* 当有错误发生时将抛出异常
*/
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
IoBuffer ioBuffer = (IoBuffer) message;
byte[] buffer = new byte[ioBuffer.limit()];
ioBuffer.get(buffer);
System.out.println("报文的长度:" + ioBuffer.limit());
//报文内容
String msg = bytesToHexString(buffer);
System.out.println("报文内容:" + msg);
//返回数据给客户端
byte[] res = HexToByte(msg);
// 组织IoBuffer数据包的方法:本方法才可以正确地让客户端UDP收到byte数组
IoBuffer buf = IoBuffer.wrap(res);
// 向客户端写数据
// SocketAddress remoteAddress = session.getRemoteAddress();
WriteFuture future = session.write(buf);
// 在100毫秒超时间内等待写完成
future.awaitUninterruptibly(100);
// The message has been written successfully
if (future.isWritten()) {
// send sucess!
System.out.println("数据发送成功:" + bytesToHexString(res));
}
// The messsage couldn't be written out completely for some reason.
// (e.g. Connection is closed)
else {
System.out.println("回复给客户端的数据发送失败!");
}
}
/**
* byte[]转换为16进制字符串
* @param src byte[]数组
* @return String
*/
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if ((src == null) || (src.length <= 0)) {
return null;
}
for (int i = 0; i < src.length; ++i) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* 16进制字符串转换为byte[]
* @param hexString 16进制字符串
* @return byte[]
*/
public static byte[] HexToByte(String hexString){
int len = hexString.length();
byte[] b = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
// 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个字节
b[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character
.digit(hexString.charAt(i + 1), 16));
}
return b;
}
}