一报文封装类
AbstractPortalMsg.java
Portal 协议数据报文封装类
- package org.yoki.edu.common.protocol.portal.msg;
- import lombok.Data;
- import lombok.ToString;
- import org.yoki.edu.common.protocol.portal.msg.attr.MsgAttr;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * Portal 协议数据报文封装类
- *
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/24$ 19:16$
- */
- @Data
- @ToString
- public abstract class AbstractPortalMsg {
- protected int ver;
- protected int type;
- protected int papChap = 1;
- protected int rsvd = 0;
- protected int serialNo;
- protected int reqId;
- protected String userIp;
- protected int userPort = 0;
- protected int errCode;
- protected int attrNum;
- /**
- * 属性列表
- */
- protected List<MsgAttr> attrList = new ArrayList<>();
- /**
- * 添加属性的方法
- *
- * @param attr
- * @return
- */
- public List<MsgAttr> addMsgAttr(MsgAttr attr) {
- if (null == attrList) {
- attrList = new ArrayList<>();
- }
- attrList.add(attr);
- return attrList;
- }
- /**
- * 将 hander 部分的字段转化为 16 个字节
- *
- * @return
- */
- protected byte[] getHander16Bytes() {
- byte[] b = new byte[16];
- b[0] = (byte) (ver & 0xff);
- b[1] = (byte) (type & 0xff);
- b[2] = (byte) (papChap & 0xff);
- b[3] = (byte) (rsvd & 0xff);
- b[4] = (byte) (serialNo >> 8 & 0xff);
- b[5] = (byte) (serialNo & 0xff);
- b[6] = (byte) (reqId >> 8 & 0xff);
- b[7] = (byte) (reqId & 0xff);
- byte[] ip = ipv4Address2BinaryArray(userIp);
- System.arraycopy(ip, 0, b, 8, 4);
- b[12] = (byte) (userPort >> 8 & 0xff);
- b[13] = (byte) (userPort & 0xff);
- b[14] = (byte) (errCode & 0xff);
- b[15] = (byte) (attrNum & 0xff);
- return b;
- }
- /**
- * 将属性列表转化为字节数组
- *
- * @return
- */
- protected byte[] getAttrBytes() {
- int attrByteNum = 0;
- if (attrList != null && !attrList.isEmpty()) {
- for (MsgAttr a : attrList) {
- attrByteNum += a.getAttrLen();
- }
- }
- byte[] b = new byte[attrByteNum];
- int index = 0;
- if (attrList != null && !attrList.isEmpty()) {
- for (MsgAttr a : attrList) {
- System.arraycopy(a.getByteValues(), 0, b, index, a.getByteValues().length);
- index += a.getByteValues().length;
- }
- }
- return b;
- }
- /**
- * 抽象方法: 获取该报文类的字节数组 < br>
- * 抽象出该方法是因为移动 Portal 和华为 Portal 协议有些区别 < br>
- * 华为 Portal 有一个 MD5 加密字段
- *
- * @return
- */
- public abstract byte[] toByteArray();
- /**
- * 抽象方法: 通过报文字节数组, 解析出各个字段值, 并赋值 < br>
- * 抽象出该方法是因为移动 Portal 和华为 Portal 协议有些区别 < br>
- * 华为 Portal 有一个 MD5 加密字段
- *
- * @param input Portal 协议报文字节数组
- */
- public abstract void parse(byte[] input);
- /**
- * 通过报文字节数组, 解析出 header 部分的信息, 并赋值
- *
- * @param input Portal 协议报文字节数组
- */
- protected void parseHeader(byte[] input) {
- this.setVer(input[0]);
- this.setType(input[1]);
- this.setPapChap(input[2]);
- this.setRsvd(input[3]);
- this.setSerialNo(((0xff & input[4]) << 8) | (0xff & input[5]));
- this.setReqId(((0xff & input[6]) << 8) | (0xff & input[7]));
- this.setUserIp((input[8] & 0xff) + "." + (input[9] & 0xff) + "." + (input[10] & 0xff) + "." + (input[11] & 0xff));
- this.setUserPort(((0xff & input[12]) << 8) | (0xff & input[13]));
- this.setErrCode(0xff & input[14]);
- this.setAttrNum(0xff & input[15]);
- }
- /**
- * 通过报文字节数组, 解析出 attr 部分的信息, 并赋值
- *
- * @param attrBytes attr 数组的字节数组
- * @param attrNum attr 的个数
- */
- protected void parseAttr(byte[] attrBytes, int attrNum) {
- List<MsgAttr> attrList = new ArrayList<MsgAttr>();
- int count = attrNum;
- if (count > 0) {
- int t = 0;
- for (int i = 0; i < count; i++) {
- int attrType = attrBytes[t];
- int attrLen = attrBytes[t + 1];
- byte[] d = new byte[attrLen - 2];
- System.arraycopy(attrBytes, t + 2, d, 0, attrLen - 2);
- MsgAttr c = new MsgAttr(attrType, new String(d));
- attrList.add(c);
- t += c.getAttrLen();
- }
- }
- this.setAttrList(attrList);
- }
- /**
- * IP 地址转换工具方法, 将 IP 字符串转换为字节数组
- *
- * @param ipAdd
- * @return
- */
- protected byte[] ipv4Address2BinaryArray(String ipAdd) {
- byte[] binIP = new byte[4];
- String[] strs = ipAdd.split("\\.");
- for (int i = 0; i < strs.length; i++) {
- binIP[i] = (byte) Integer.parseInt(strs[i]);
- }
- return binIP;
- }
- }
- View Code
- PortalV1Msg.java
移动 Portal 协议数据报文封装类
- package org.yoki.edu.common.protocol.portal.msg;
- import lombok.NoArgsConstructor;
- import org.yoki.edu.common.protocol.portal.msg.attr.MsgAttr;
- import java.util.List;
- /**
- * 移动 Portal 协议数据报文封装类
- *
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/25$ 14:52$
- */
- @NoArgsConstructor
- public class PortalV1Msg extends AbstractPortalMsg {
- public PortalV1Msg(int ver, int type, int serialNo, int reqId, String userIp, int errCode, int attrNum, List<MsgAttr> attr) {
- super();
- this.ver = ver;
- this.type = type;
- this.serialNo = serialNo;
- this.reqId = reqId;
- this.userIp = userIp;
- this.errCode = errCode;
- this.attrNum = attrNum;
- this.attrList = attr;
- }
- public PortalV1Msg(int ver, int type, int papChap, int rsvd, int serialNo, int reqId, String userIp, int userPort,
- int errCode, int attrNum, List<MsgAttr> attr) {
- super();
- this.ver = ver;
- this.type = type;
- this.papChap = papChap;
- this.rsvd = rsvd;
- this.serialNo = serialNo;
- this.reqId = reqId;
- this.userIp = userIp;
- this.userPort = userPort;
- this.errCode = errCode;
- this.attrNum = attrNum;
- this.attrList = attr;
- }
- @Override
- public byte[] toByteArray() {
- byte[] headerBytes = getHander16Bytes();
- byte[] attrBytes = getAttrBytes();
- byte[] b = new byte[headerBytes.length + attrBytes.length];
- if (null != headerBytes && headerBytes.length > 0) {
- System.arraycopy(headerBytes, 0, b, 0, headerBytes.length);
- }
- b[15] = (byte) this.attrList.size();
- if (null != attrBytes && attrBytes.length > 0) {
- System.arraycopy(attrBytes, 0, b, 16, attrBytes.length);
- }
- return b;
- }
- @Override
- public void parse(byte[] input) {
- if (null != input && input.length >= 16) {
- byte[] headerBytes = new byte[16];
- System.arraycopy(input, 0, headerBytes, 0, headerBytes.length);
- this.parseHeader(headerBytes);
- int attrNum = input[15];
- byte[] attrBytes = new byte[input.length - 16];
- System.arraycopy(input, 16, attrBytes, 0, attrBytes.length);
- parseAttr(attrBytes, attrNum);
- }
- }
- }
- View Code
- MsgAttr.java
Portal 数据报文 Attr 字段封装父类
- package org.yoki.edu.common.protocol.portal.msg.attr;
- import lombok.Data;
- import lombok.Getter;
- import lombok.NoArgsConstructor;
- import java.util.Arrays;
- /**
- * Portal 数据报文 Attr 字段封装父类
- *
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/24$ 20:44$
- */
- @Data
- public class MsgAttr {
- private int attrType;
- private int attrLen;
- private String attrValue;
- private byte[] byteValues;
- protected MsgAttr() {
- }
- public MsgAttr(int attrType, String attrValue) {
- this.attrType = attrType;
- this.attrLen = 2 + attrValue.getBytes().length;
- this.attrValue = attrValue;
- byteValues = new byte[attrLen];
- byteValues[0] = (byte) attrType;
- byteValues[1] = (byte) attrLen;
- System.arraycopy(attrValue.getBytes(), 0, byteValues, 2, attrValue.getBytes().length);
- }
- }
- View Code
- UserNameMsgAttr.java
- package org.yoki.edu.common.protocol.portal.msg.attr;
- /**
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/29$ 15:05$
- */
- public class UserNameMsgAttr extends MsgAttr {
- public UserNameMsgAttr(String userName){
- super(0x01 , userName) ;
- }
- }
- View Code
- PasswordMsgAttr.java
- package org.yoki.edu.common.protocol.portal.msg.attr;
- /**
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/29$ 15:08$
- */
- public class PasswordMsgAttr extends MsgAttr {
- public PasswordMsgAttr(String password){
- super(0x02 , password) ;
- }
- }
- View Code
- ChallengeMsgAttr.java
- package org.yoki.edu.common.protocol.portal.msg.attr;
- /**
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/29$ 15:09$
- */
- public class ChallengeMsgAttr extends MsgAttr {
- public ChallengeMsgAttr(String challenge){
- super(0x03 , challenge) ;
- }
- }
- View Code
- ChapPasswordMsgAttr.java
- package org.yoki.edu.common.protocol.portal.msg.attr;
- /**
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/29$ 15:09$
- */
- public class ChapPasswordMsgAttr extends MsgAttr {
- public ChapPasswordMsgAttr(String chapPassword){
- super(0x04 , chapPassword) ;
- }
- }
- View Code
二工具类
ChapEncryptUtils.java
Chap 加密工具类
- package org.yoki.edu.common.protocol.portal.utils;
- import org.yoki.edu.common.utils.encrypt.EncryptUtils;
- /**
- * Chap 加密
- *
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/27$ 17:20$
- */
- public class ChapEncryptUtils {
- public static byte[] encryptChap(int reqId, String challenge, String pwd) {
- byte[] chapPwd = encryptChap(reqId, challenge.getBytes(), pwd.getBytes());
- return chapPwd;
- }
- public static byte[] encryptChap(int reqId, byte[] challenge, byte[] pwd) {
- /**
- * Chap_Password(Chap 密码) 的生成:
- * Chap_Password 的生成遵循标准的 Radious 协议中的 Chap_Password 生成方法 (参见 RFC2865)
- * 密码加密使用 MD5 算法, MD5 函数的输入为 ChapID + Password +Challenge (reqId 有 AC 生成, ChapID 是 ReqID 的低 8 位)
- * 其中, ChapID 取 reqId 的低 8 位, Password 的长度不够协议规定的最大长度, 其后不需要补零
- * Chap_Password = MD5 (ChapID+ Password + Challenge )
- */
- byte[] buf = new byte[1 + pwd.length + challenge.length];
- buf[0] = (byte) (reqId & 0xff);
- System.arraycopy(pwd, 0, buf, 1, pwd.length);
- System.arraycopy(challenge, 0, buf, 1 + pwd.length, challenge.length);
- byte[] chapPwd = EncryptUtils.encryptMD5Bytes(buf);
- return chapPwd;
- }
- }
- View Code
三 Portal 协议工具类
PortalV1ChapMsgBuilder.java
CHAP 方式 Portal 报文生产工具类
- package org.yoki.edu.common.protocol.portal.v1.builder;
- import org.yoki.edu.common.protocol.portal.msg.attr.UserNameMsgAttr;
- import org.yoki.edu.common.protocol.portal.utils.ChapEncryptUtils;
- import org.yoki.edu.common.protocol.portal.msg.PortalV1Msg;
- import org.yoki.edu.common.protocol.portal.msg.attr.ChapPasswordMsgAttr;
- /**
- * CHAP 方式 Portal 报文生产工具类
- *
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/29$ 14:37$
- */
- public class PortalV1ChapMsgBuilder {
- /**
- * 生成 Chanllenge 请求报文
- *
- * @param serialNo
- * @param userIp 用户 IP
- * @return
- */
- public PortalV1Msg buildReqChallengeMsg(int serialNo, String userIp) {
- PortalV1Msg msg = buildV1ChapMsg();
- msg.setType(1);
- msg.setReqId(0);
- msg.setSerialNo(serialNo);
- msg.setUserIp(userIp);
- msg.setAttrNum(0);
- return msg;
- }
- /**
- * 生成认证请求报文
- *
- * @param reqId
- * @param serialNo
- * @param userIp
- * @param userName
- * @param password
- * @param challenge
- * @return
- */
- public PortalV1Msg buildReqAuthMsg(int reqId, int serialNo, String userIp, String userName, String password, String challenge) {
- PortalV1Msg msg = buildV1ChapMsg();
- msg.setType(3);
- msg.setSerialNo(serialNo);
- msg.setReqId(reqId);
- msg.setUserIp(userIp);
- msg.setAttrNum(2);
- UserNameMsgAttr userNameMsgAttr = new UserNameMsgAttr(userName);
- byte[] chapPassworldBytes = ChapEncryptUtils.encryptChap(reqId, challenge, password);
- ChapPasswordMsgAttr chapPasswordMsgAttr = new ChapPasswordMsgAttr(new String(chapPassworldBytes));
- msg.addMsgAttr(userNameMsgAttr).add(chapPasswordMsgAttr);
- return msg;
- }
- /**
- * 生成下线请求报文
- *
- * @param reqId
- * @param serialNo
- * @param userIp
- * @return
- */
- public PortalV1Msg buildReqLogoutMsg(int reqId, int serialNo, String userIp) {
- PortalV1Msg msg = buildV1ChapMsg();
- msg.setType(5);
- msg.setSerialNo(serialNo);
- msg.setReqId(reqId);
- msg.setUserIp(userIp);
- msg.setAttrNum(0);
- return msg;
- }
- /**
- * 生成认证接收响应报文
- *
- * @param reqId
- * @param serialNo
- * @param userIp
- * @return
- */
- public PortalV1Msg buildAffAckAuthMsg(int reqId, int serialNo, String userIp) {
- PortalV1Msg msg = buildV1ChapMsg();
- msg.setType(7);
- msg.setSerialNo(serialNo);
- msg.setReqId(reqId);
- msg.setUserIp(userIp);
- msg.setAttrNum(0);
- return msg;
- }
- private PortalV1Msg buildV1ChapMsg() {
- PortalV1Msg msg = new PortalV1Msg();
- msg.setVer(1);
- msg.setPapChap(0);
- msg.setRsvd(0);
- msg.setUserPort(0);
- msg.setErrCode(0);
- return msg;
- }
- }
- View Code
- PortalV1PapMsgBuilder.java
PAP 方式 Portal 报文生产工具类
- package org.yoki.edu.common.protocol.portal.v1.builder;
- import org.yoki.edu.common.protocol.portal.msg.PortalV1Msg;
- import org.yoki.edu.common.protocol.portal.msg.attr.PasswordMsgAttr;
- import org.yoki.edu.common.protocol.portal.msg.attr.UserNameMsgAttr;
- /**
- * PAP 方式 Portal 报文生产工具类
- *
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/29$ 14:37$
- */
- public class PortalV1PapMsgBuilder {
- /**
- * 生成认证请求报文
- *
- * @param serialNo
- * @param userIp
- * @param userName
- * @param password
- * @return
- */
- public PortalV1Msg buildReqAuthMsg(int serialNo, String userIp, String userName, String password) {
- PortalV1Msg msg = buildV1PapMsg();
- msg.setType(3);
- msg.setSerialNo(serialNo);
- msg.setUserIp(userIp);
- msg.setAttrNum(2);
- UserNameMsgAttr userNameMsgAttr = new UserNameMsgAttr(userName);
- PasswordMsgAttr passwordMsgAttr = new PasswordMsgAttr(password);
- msg.addMsgAttr(userNameMsgAttr).add(passwordMsgAttr);
- return msg;
- }
- /**
- * 生成下线请求报文
- *
- * @param serialNo
- * @param userIp
- * @return
- */
- public PortalV1Msg buildReqLogoutMsg(int serialNo, String userIp) {
- PortalV1Msg msg = buildV1PapMsg();
- msg.setType(5);
- msg.setSerialNo(serialNo);
- msg.setUserIp(userIp);
- msg.setAttrNum(0);
- return msg;
- }
- /**
- * 生成认证接收响应报文
- *
- * @param serialNo
- * @param userIp
- * @return
- */
- public PortalV1Msg buildAffAckAuthMsg(int serialNo, String userIp) {
- PortalV1Msg msg = buildV1PapMsg();
- msg.setType(7);
- msg.setSerialNo(serialNo);
- msg.setUserIp(userIp);
- msg.setAttrNum(0);
- return msg;
- }
- private PortalV1Msg buildV1PapMsg() {
- PortalV1Msg msg = new PortalV1Msg();
- msg.setVer(1);
- msg.setPapChap(1);
- msg.setRsvd(0);
- msg.setReqId(0);
- msg.setUserPort(0);
- msg.setErrCode(0);
- return msg;
- }
- }
- View Code
- PortalV1MsgParser.java
报文解析工具类
- package org.yoki.edu.common.protocol.portal.v1.parser;
- import org.yoki.edu.common.protocol.portal.exception.PortalException;
- import org.yoki.edu.common.protocol.portal.exception.enums.PortalErrorStatusEnum;
- import org.yoki.edu.common.protocol.portal.msg.PortalV1Msg;
- /**
- * 报文解析工具类
- *
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/29$ 15:59$
- */
- public class PortalV1MsgParser {
- private final int ACK_CHALLENGE = 0X02;
- private final int ACK_AUTH = 0X04;
- private final int ACK_LOGOUT = 0X06;
- private final int ERROR_CODE_1 = 1;
- private final int ERROR_CODE_2 = 2;
- private final int ERROR_CODE_3 = 3;
- private final int ERROR_CODE_4 = 4;
- public PortalV1Msg parse(byte[] input) throws PortalException {
- PortalV1Msg msg = new PortalV1Msg();
- msg.parse(input);
- parse(msg);
- return msg;
- }
- public void parse(PortalV1Msg msg) throws PortalException {
- Integer type = msg.getType();
- Integer errorCode = msg.getErrCode();
- PortalErrorStatusEnum[] enums = PortalErrorStatusEnum.values();
- for (PortalErrorStatusEnum e : enums) {
- if (e.getErrCode() == errorCode && e.getType() == type) {
- throw new PortalException(e);
- }
- }
- }
- }
- View Code
- PortalV1PapMsgSender.java
Portal 报文发送工具类
内部调用 DatagramSocket 进行 UDP 报文发送
- package org.yoki.edu.common.protocol.portal.v1.sender;
- import lombok.Getter;
- import lombok.Setter;
- import org.yoki.edu.common.protocol.portal.v1.builder.PortalV1PapMsgBuilder;
- import org.yoki.edu.common.protocol.portal.exception.PortalException;
- import org.yoki.edu.common.protocol.portal.msg.PortalV1Msg;
- import org.yoki.edu.common.protocol.portal.v1.parser.PortalV1MsgParser;
- import java.io.IOException;
- import java.net.DatagramPacket;
- import java.net.DatagramSocket;
- import java.net.InetAddress;
- /**
- * Portal 报文发送工具类 < br>
- * 内部调用 DatagramSocket 进行 UDP 报文发送
- *
- * @author Sky$
- * @Description: TODO
- * @date 2017/10/31$ 17:57$
- */
- public class PortalV1PapMsgSender {
- @Setter
- @Getter
- private int timeOut = 5000;
- @Setter
- @Getter
- private Integer receiverPort = null;
- /**
- * REQ_AUTH 0x03 Client----->Server AbstractPortalMsg Server 向 AC 设备发送的请求认证报文
- *
- * @param serialNo
- * @param loginIp
- * @param loginName
- * @param password
- * @param acIp
- * @param acPort
- * @return
- * @throws Exception
- */
- public byte[] sendReqAuth(int serialNo, String loginIp, String loginName, String password, String acIp, int acPort) throws IOException {
- DatagramSocket dataSocket = null;
- byte[] ackData = new byte[0];
- dataSocket = null;
- DatagramPacket requestPacket = null;
- PortalV1PapMsgBuilder builder = new PortalV1PapMsgBuilder();
- PortalV1Msg msg = builder.buildReqAuthMsg(serialNo, loginIp, loginName, password);
- byte[] msgBytes = msg.toByteArray();
- // 创建连接
- if (null != receiverPort) {
- dataSocket = new DatagramSocket(receiverPort);
- } else {
- dataSocket = new DatagramSocket();
- }
- // 创建发送数据包并发送给服务器
- requestPacket = new DatagramPacket(msgBytes, msgBytes.length, InetAddress.getByName(acIp), acPort);
- ackData = new byte[1024];
- // 接收服务器的数据包
- DatagramPacket receivePacket = new DatagramPacket(ackData, 32);
- // 设置请求超时 3 秒
- dataSocket.setSoTimeout(timeOut);
- dataSocket.send(requestPacket);
- dataSocket.receive(receivePacket);
- if (null != dataSocket) {
- dataSocket.disconnect();
- dataSocket.close();
- }
- return ackData;
- }
- /**
- * REQ_AUTH 0x03 Client----->Server AbstractPortalMsg Server 向 AC 设备发送的请求认证报文
- *
- * @param serialNo
- * @param loginIp
- * @param loginName
- * @param password
- * @param acIp
- * @param acPort
- * @return
- * @throws Exception
- */
- public PortalV1Msg sendAndParseReqAuth(int serialNo, String loginIp, String loginName, String password, String acIp, int acPort) throws PortalException, IOException {
- byte[] ackData = sendReqAuth(serialNo, loginIp, loginName, password, acIp, acPort);
- PortalV1MsgParser msgParser = new PortalV1MsgParser();
- PortalV1Msg reciveMsg = msgParser.parse(ackData);
- reciveMsg.parse(ackData);
- return reciveMsg;
- }
- /**
- * AbstractPortalMsg Server 对收到的认证成功响应报文的确认报文;
- *
- * @param serialNo
- * @param loginIp
- * @param acIp
- * @param acPort
- * @throws Exception
- */
- public void sendAffAckAuth(int serialNo, String loginIp, String acIp, int acPort) throws IOException {
- DatagramSocket dataSocket = null;
- PortalV1PapMsgBuilder builder = new PortalV1PapMsgBuilder();
- PortalV1Msg msg = builder.buildAffAckAuthMsg(serialNo, loginIp);
- byte[] msgBytes = msg.toByteArray();
- // 创建连接
- if (null != receiverPort) {
- dataSocket = new DatagramSocket(receiverPort);
- } else {
- dataSocket = new DatagramSocket();
- }
- // 创建发送数据包并发送给服务器
- DatagramPacket requestPacket = new DatagramPacket(msgBytes, msgBytes.length, InetAddress.getByName(acIp), acPort);
- // 接收服务器的数据包
- dataSocket.send(requestPacket);
- if (null != dataSocket) {
- dataSocket.disconnect();
- dataSocket.close();
- }
- }
- /**
- * AbstractPortalMsg Server 向 AC 设备发送的请求用户下线报文
- *
- * @param serialNo
- * @param loginIp
- * @param acIp
- * @param acPort
- * @return
- * @throws Exception
- */
- public byte[] sendReqLogout(int serialNo, String loginIp, String acIp, int acPort) throws IOException {
- DatagramSocket dataSocket = null;
- byte[] ackData = new byte[0];
- PortalV1PapMsgBuilder builder = new PortalV1PapMsgBuilder();
- PortalV1Msg msg = builder.buildReqLogoutMsg(serialNo, loginIp);
- byte[] msgBytes = msg.toByteArray();
- // 创建连接
- if (null != receiverPort) {
- dataSocket = new DatagramSocket(receiverPort);
- } else {
- dataSocket = new DatagramSocket();
- }
- // 创建发送数据包并发送给服务器
- DatagramPacket requestPacket = new DatagramPacket(msgBytes, msgBytes.length, InetAddress.getByName(acIp), acPort);
- ackData = new byte[1024];
- // 接收服务器的数据包
- DatagramPacket receivePacket = new DatagramPacket(ackData, 32);
- // 设置请求超时 3 秒
- dataSocket.setSoTimeout(timeOut);
- dataSocket.send(requestPacket);
- dataSocket.receive(receivePacket);
- if (null != dataSocket) {
- dataSocket.disconnect();
- dataSocket.close();
- }
- return ackData;
- }
- /**
- * AbstractPortalMsg Server 向 AC 设备发送的请求用户下线报文
- *
- * @param serialNo
- * @param loginIp
- * @param acIp
- * @param acPort
- * @return
- * @throws Exception
- */
- public PortalV1Msg sendAndParseReqLogout(int serialNo, String loginIp, String acIp, int acPort) throws IOException, PortalException {
- byte[] ackData = sendReqLogout(serialNo, loginIp, acIp, acPort);
- PortalV1MsgParser msgParser = new PortalV1MsgParser();
- PortalV1Msg reciveMsg = msgParser.parse(ackData);
- reciveMsg.parse(ackData);
- return reciveMsg;
- }
- }
- View Code
四使用示例
- /**
- * 用户短信认证
- *
- * @param vo
- * @return
- */
- @RequestMapping(value = "userAuth", method = RequestMethod.POST)
- public InvokeResult userAuth(MobileAuthReqVo vo) {
- InvokeResult invokeResult = null;
- if (null == vo || CommonUtils.isEmpty(vo.getLoginname(), vo.getPassword())) {
- invokeResult = InvokeResult.failure("请填写手机号和验证码!");
- } else if (!CommonUtils.isChinaPhoneLegal(vo.getLoginname())) {
- invokeResult = InvokeResult.failure("手机号格式有误!");
- } else {
- // 用户登陆 IP
- String loginIp = vo.getUserpriip();
- int serialNo = (int) (65535 * Math.random());
- PortalV1PapMsgSender sender = new PortalV1PapMsgSender();
- sender.setTimeOut(60000);
- try {
- PortalV1Msg reciveMsg = sender.sendAndParseReqAuth(serialNo, loginIp, vo.getLoginname(), vo.getPassword(), acIp, acPort);
- sender.sendAffAckAuth(serialNo, loginIp, acIp, acPort);
- // 重置密码, 防止密码可以多次使用
- Radcheck radcheck = new Radcheck() ;
- radcheck.setUsername(vo.getLoginname());
- radcheck.setLoginIp(loginIp);
- radcheck.setDeviceMac(vo.getDeviceMac());
- radcheck.updateIpAndMac();
- invokeResult = InvokeResult.ok();
- } catch (BizException e) {
- e.printStackTrace();
- invokeResult = InvokeResult.failure(e.getMessage());
- } catch (Exception e) {
- e.printStackTrace();
- invokeResult = InvokeResult.error();
- }
- }
- return invokeResult;
- }
- View Code
来源: http://www.bubuko.com/infodetail-2514648.html