关于长连接socket,相信很多朋友都不陌生,和很多朋友一样,都喜欢去网上找一些第三方框架来用
不过在年底面试的时候,被问到这一块的时候,信口而来的第三方遭到了面试官的鄙视
新项目需要做到长连相关,所以就主动提议手写一个第三方
当然很多人会觉得很简单,不过基于最近也是被基友给问到了,所以给出如下的代码
1.建立socket连接:
socket = new Socket(ApiConst.SOCKET_MYAPP, ApiConst.SOCKET_MYAPP_DK);2.发送socket:
public class SendSocket { public static void sendSocket(final String socketData) { new Thread(new Runnable() { @Override public void run() { try { String base64Token = CodeUtils.encode( socketData); // BufferedWriter writer = new BufferedWriter(new OutputStreamWriter( // ApiConst.SOCKET.getOutputStream())); OutputStream outputStream = ApiConst.SOCKET.getOutputStream(); byte[] data1 = base64Token.getBytes();3.接收socket,关于粘包和半包的处理,代码中都已经处理好了:byte[] data2 = new byte[data1.length];byte[] data3 = new byte[data1.length + data2.length];
System.arraycopy(data2, 0, data3, 0, data2.length);
System.arraycopy(data1, 0, data3, data2.length, data1.length);
outputStream.write(data3);
outputStream.flush();//
writer.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
InputStream is = null; byte[] Alldata = new byte[0]; try { is = ApiConst.SOCKET.getInputStream(); byte[] data = new byte[1024]; int temp = -1; while ((temp = is.read(data)) != -1) { //没收到数据会暂停在这里的. byte[] tmpdata = new byte[Alldata.length + temp]; if (Alldata.length > 0) { System.arraycopy(Alldata, 0, tmpdata, 0, Alldata.length); } System.arraycopy(data, 0, tmpdata, Alldata.length, temp); Alldata = tmpdata; while (Alldata.length >= 4) { int packegLenth = Alldata.lenth; if (packetLength > 10 * 1024 * 1024) {//最大Buffer异常保护 Alldata = new byte[0]; break; } if (Alldata.length - 4 < packetLength) break; if (Alldata.length - 4 >= packetLength) { //收到的数据达到包长度 byte[] packet = new byte[packetLength]; System.arraycopy(Alldata, 4, packet, 0, packetLength); packetLength = Alldata.length - 4 - packetLength; if (packetLength > 0) { tmpdata = Alldata; Alldata = new byte[packetLength]; System.arraycopy(tmpdata, packet.length + 4, Alldata, 0, packetLength); } else { Alldata = new byte[0]; } String message = new String(packet);4.接下来就是保持长连的心跳包了:
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(ApiConst.SOCKET.getOutputStream()); BufferedWriter writer = new BufferedWriter(outputStreamWriter); writer.write("longConnect");//这个关键字和服务端协商,一些博客里会写Socket.sendUrgentData(0xff)这个方法,当然建议不要用,具体原因在前几篇博文里已经提到 writer.flush();代码很简单,如果还有不清楚的,这段时间会整理成demo传到下载区