这个是阿里的一道面试题,我看到后很感兴趣,因为最近我写了几个银行接口都是用的scoket技术进行的数据接收和返回。这个面试题我在网上也没找到具体的答案,所有我就根据我项目的实际情况和我的理解进行分析。为了防止scoket接收数据丢失,我们项目采取的做法是
第一:循环接收数据 where(true){接收报文的代码}
第二:接收的报文和银行约定,前6位报文体是所发送报文的总长度。先接收6字节的报文长度,就可以获取到报文总长度,这样如果接收的报文长度不够就会阻塞状态,直到报文全部接收完毕为止。
接收流程如图:
接收报文的核心代码如下:
where(true){
final Socket socket = serverSocket.accept();
InputStream inputStream = null;
DataInputStream input = null;
byte[] xml_byte = null;
try {
inputStream = socket.getInputStream();
//获取二进制流报文信息
input = new DataInputStream(inputStream);
int readedLen;
// 获取报文长度
byte[] lenBytes = new byte[6];
for (readedLen = 0; readedLen < lenBytes.length; ) {
int temp = input.read(lenBytes, readedLen, lenBytes.length - readedLen);
if(temp <= 0) {
throw new Exception("接收报文长度错误!");
}
readedLen += temp;
}
int len = Integer.parseInt(new String(lenBytes));
logger.info("接收的消息长度:" + len);
byte[] bodyBytes = new byte[len];
for (readedLen = 0; readedLen < bodyBytes.length; ) {
int temp = input.read(bodyBytes, readedLen, bodyBytes.length - readedLen);
if(temp <= 0){
throw new Exception("接收报文体错误!");
}
readedLen += temp;
}
xml_byte = new byte[6 + len];
System.arraycopy(lenBytes, 0, xml_byte, 0, 6);
System.arraycopy(bodyBytes, 0, xml_byte, 6, len);
} catch (Exception e) {
e.printStackTrace();
logger.error("接收报文异常!", e);
//socket.close();
return;
}
}