• Java TCP服务端多线程接收RFID网络读卡器上传数据


    本示例使用设备介绍:WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com)

    1. import java.io.IOException;
    2. import java.io.InputStream;
    3. import java.io.OutputStream;
    4. import java.net.ServerSocket;
    5. import java.net.Socket;
    6. import java.util.Arrays;
    7. public class TCPServer_Java {
    8. //监听端口
    9. private static final int PORT = 39169;
    10. public static void main(String[] args) throws IOException {
    11. ServerSocket serverSocket = null;
    12. Socket socket = null;
    13. try {
    14. //建立服务器的Socket,并设定一个监听的端口PORT
    15. serverSocket = new ServerSocket(PORT);
    16. //由于需要进行循环监听,因此获取消息的操作应放在一个while大循环中
    17. while(true){
    18. try {
    19. //建立跟客户端的连接
    20. socket = serverSocket.accept();
    21. ServerThread thread = new ServerThread(socket);
    22. thread.start();
    23. } catch (Exception e) {
    24. System.out.println("建立与客户端的连接出现异常");
    25. e.printStackTrace();
    26. }
    27. //ServerThread thread = new ServerThread(socket);
    28. //thread.start();
    29. }
    30. } catch (Exception e) {
    31. System.out.println("端口被占用");
    32. e.printStackTrace();
    33. }
    34. finally {
    35. serverSocket.close();
    36. }
    37. }
    38. }
    39. //服务端线程类
    40. //继承Thread类的话,必须重写run方法,在run方法中定义需要执行的任务。
    41. class ServerThread extends Thread {
    42. private Socket socket ;
    43. InputStream inputStream;
    44. OutputStream outputStream;
    45. public ServerThread(Socket socket){
    46. this.socket=socket;
    47. }
    48. public void run(){
    49. try {
    50. while (true){
    51. //接收客户端的消息,解析信息并回应读卡器
    52. //System.out.println(socket);
    53. byte[] bytes =new byte[1024];
    54. inputStream =socket.getInputStream();
    55. int GetDataLen=0;
    56. while ((GetDataLen=inputStream.read(bytes))!=-1){ //通过这个方法读取全部数据 及 长度,
    57. break;
    58. }
    59. if(GetDataLen>0) {
    60. String bytestr = "";
    61. String DataStr = "";
    62. String DispStr = "";
    63. String CardNo16 = "";
    64. String SerialNum = "";
    65. long cardno10;
    66. long cardnum;
    67. for (int p = 0; p < GetDataLen; p++) {
    68. bytestr = "00" + Integer.toHexString(bytes[p] & 0xff);
    69. DataStr = DataStr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";
    70. }
    71. System.out.println("Received from " + socket.getRemoteSocketAddress() + " : " + DataStr);
    72. switch (bytes[0]) {
    73. case (byte)0xc1:
    74. case (byte)0xcf:
    75. if(bytes[0]==(byte)0xc1){
    76. DispStr = "数据解析:接收到读取IC卡号信息,";
    77. }else{DispStr = "数据解析:接收到IC卡离开读卡器,";}
    78. DispStr = DispStr + "功能码:" + Integer.toHexString(bytes[0] & 0xff);
    79. DispStr = DispStr + ",设备IP:" + Integer.toString(bytes[1] & 0xff) + "." + Integer.toString(bytes[2] & 0xff) + "." + Integer.toString(bytes[3] & 0xff) + "." + Integer.toString(bytes[4] & 0xff);
    80. DispStr = DispStr + ",机号:" + Integer.toString((bytes[5] & 0xff) + ((bytes[6] & 0xff) * 256));
    81. DispStr = DispStr + ",数据包序号:" + Integer.toString((bytes[7] & 0xff) + ((bytes[8] & 0xff) * 256));
    82. int Cardlen = bytes[9];
    83. DispStr = DispStr + ",卡号长度:" + Integer.toString(Cardlen);
    84. CardNo16 = "";
    85. for (int p = 10; p < 10 + Cardlen; p++) {
    86. bytestr = "00" + Integer.toHexString(bytes[p] & 0xff);
    87. CardNo16 = CardNo16 + bytestr.substring(bytestr.length() - 2, bytestr.length());
    88. }
    89. DispStr = DispStr + ",16进制卡号:" + CardNo16;
    90. cardnum = bytes[10] & 0xff;
    91. cardnum = cardnum + (bytes[11] & 0xff) * 256;
    92. cardnum = cardnum + (bytes[12] & 0xff) * 65536;
    93. cardnum = cardnum + (bytes[13] & 0xff) * 16777216;
    94. cardno10 = 0;
    95. for (int j = 28; j >= 0; j -= 4) {
    96. cardno10 = cardno10 << 4 | (cardnum >>> j & 0xF);
    97. }
    98. DispStr = DispStr + ",转10进制卡号:" + String.format("%010d", cardno10);
    99. SerialNum = "";
    100. for (int p = 10 + Cardlen; p < GetDataLen; p++) {
    101. bytestr = "00" + Integer.toHexString(bytes[p] & 0xff);
    102. SerialNum = SerialNum + bytestr.substring(bytestr.length() - 2, bytestr.length());
    103. }
    104. DispStr = DispStr + ",唯一硬件序号:" + SerialNum;
    105. System.out.println(DispStr + "\n");
    106. //向客户端发送消息
    107. byte[] RespByte=GetResponseData(2); //生成不同的回应数据包
    108. outputStream = socket.getOutputStream();
    109. outputStream.write(RespByte);
    110. bytestr = "";
    111. DataStr = "";
    112. for (int p = 0; p < RespByte.length; p++) {
    113. bytestr = "00" + Integer.toHexString(RespByte[p] & 0xff);
    114. DataStr = DataStr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";
    115. }
    116. System.out.println("Send Data To "+socket.getRemoteSocketAddress()+" : "+DataStr+"\n");
    117. break;
    118. case (byte)0xd1:
    119. case (byte)0xdf:
    120. if(bytes[0]==(byte)0xd1){
    121. DispStr="数据解析:接收到读取ID卡号信息,";
    122. }else{DispStr="数据解析:接收到ID卡离开读卡器,";}
    123. DispStr=DispStr+"功能码:"+ Integer.toHexString(bytes[0] & 0xff);
    124. DispStr=DispStr+",设备IP:"+ Integer.toString(bytes[1] & 0xff) + "." + Integer.toString(bytes[2] & 0xff) + "." + Integer.toString(bytes[3] & 0xff) + "." + Integer.toString(bytes[4] & 0xff);
    125. DispStr=DispStr+",机号:"+ Integer.toString((bytes[5] & 0xff) + ((bytes[6] & 0xff) * 256));
    126. DispStr=DispStr+",数据包序号:"+ Integer.toString((bytes[7] & 0xff) + ((bytes[8] & 0xff) * 256));
    127. CardNo16="";
    128. for (int p = 9; p < 14; p++) {
    129. bytestr = "00" + Integer.toHexString(bytes[p] & 0xff);
    130. CardNo16 = CardNo16 + bytestr.substring(bytestr.length() - 2, bytestr.length());
    131. }
    132. DispStr=DispStr+",16进制卡号:"+CardNo16;
    133. cardnum = bytes[9] & 0xff;
    134. cardnum = cardnum + (bytes[10] & 0xff) * 256;
    135. cardnum = cardnum + (bytes[11] & 0xff) * 65536;
    136. cardnum = cardnum + (bytes[12] & 0xff) * 16777216;
    137. cardno10 = 0;
    138. for (int j = 28; j >= 0; j -= 4) {
    139. cardno10 = cardno10 << 4 | (cardnum >>> j & 0xF);
    140. }
    141. DispStr=DispStr+",转10进制卡号:"+ String.format("%010d", cardno10);
    142. SerialNum="";
    143. for (int p = 14; p < GetDataLen; p++) {
    144. bytestr = "00" + Integer.toHexString(bytes[p] & 0xff);
    145. SerialNum = SerialNum + bytestr.substring(bytestr.length() - 2, bytestr.length());
    146. }
    147. DispStr=DispStr+",唯一硬件序号:"+ SerialNum;
    148. System.out.println(DispStr+"\n");
    149. //向客户端发送消息
    150. RespByte=GetResponseData(2); //生成不同的回应数据包
    151. outputStream = socket.getOutputStream();
    152. outputStream.write(RespByte);
    153. bytestr = "";
    154. DataStr = "";
    155. for (int p = 0; p < RespByte.length; p++) {
    156. bytestr = "00" + Integer.toHexString(RespByte[p] & 0xff);
    157. DataStr = DataStr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";
    158. }
    159. System.out.println("Send Data To "+socket.getRemoteSocketAddress()+" : "+DataStr+"\n");
    160. break;
    161. case (byte)0xf3:
    162. DispStr="数据解析:接收到设备心跳包,";
    163. DispStr=DispStr+"功能码:"+Integer.toHexString(bytes[0] & 0xff);
    164. DispStr=DispStr+",设备IP:"+Integer.toString(bytes[1] & 0xff)+"."+Integer.toString(bytes[2] & 0xff)+"."+Integer.toString(bytes[3] & 0xff)+"."+Integer.toString(bytes[4] & 0xff);
    165. DispStr=DispStr+",机器号:"+Integer.toString((bytes[5] & 0xff)+((bytes[6] & 0xff) *256));
    166. DispStr=DispStr+",包序号:"+Integer.toString((bytes[7] & 0xff)+((bytes[8] & 0xff) *256));
    167. DispStr=DispStr+",心跳码:"+Integer.toHexString(bytes[9] & 0xff);
    168. DispStr=DispStr+",长 度:"+Integer.toHexString(bytes[10] & 0xff);
    169. DispStr=DispStr+",继电器:"+Integer.toHexString(bytes[11] & 0xff);
    170. DispStr=DispStr+",按键值:"+Integer.toHexString(bytes[12] & 0xff);
    171. for(int p=13;p<17;p++){
    172. bytestr="00"+Integer.toHexString(bytes[p] & 0xff);
    173. SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
    174. }
    175. DispStr=DispStr+",随机码:"+SerialNum;
    176. SerialNum="";
    177. for(int p=17;p
    178. bytestr="00"+Integer.toHexString(bytes[p] & 0xff);
    179. SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
    180. }
    181. DispStr=DispStr+",设备序列号:"+SerialNum;
    182. System.out.println(DispStr+"\n");
    183. break;
    184. }
    185. }
    186. }
    187. } catch (Exception e) {
    188. System.out.println("客户端主动断开连接了");
    189. e.printStackTrace();
    190. }
    191. //操作结束,关闭socket
    192. try{
    193. socket.close();
    194. }catch(IOException e){
    195. System.out.println("关闭连接出现异常");
    196. e.printStackTrace();
    197. }
    198. }
    199. //根据Respcode返回不同的回应数据包
    200. static byte[] GetResponseData(int Respcode) throws Exception {
    201. byte[] RespByte= new byte[300];
    202. String DispStr="本次刷卡成功,感谢您的使用,再见! "; //满屏显示34个字符,不足后面加空格
    203. byte[] DispBuf;
    204. switch(Respcode){
    205. case 0: //驱动读卡器蜂鸣响声
    206. RespByte[0] = (byte) 0x96; //蜂鸣响声的指令码
    207. RespByte[1] = (byte) 0x00; //机号低位
    208. RespByte[2] = (byte) 0x00; //机号高,0000表示任意机号
    209. RespByte[3] = (byte) 0x01; //蜂鸣响声代码,取值范围0-12
    210. RespByte = Arrays.copyOf(RespByte, 4);
    211. break;
    212. case 1: //驱动读卡器显示文字+蜂鸣响声
    213. DispBuf= DispStr.getBytes("gb2312"); //显示文字转字节数组
    214. RespByte[0]=(byte)0x5a; //指令码
    215. RespByte[1]=(byte)0x00; //机号低
    216. RespByte[2]=(byte)0x00; //机号高,如果高低位都为0表示任意机号
    217. RespByte[3]=(byte)0x02; //蜂鸣声代码
    218. RespByte[4]=(byte)0x14; //显示时长
    219. for(int i=0;i<34;i++){ //显示文字
    220. RespByte[i+5]=DispBuf[i];
    221. }
    222. RespByte = Arrays.copyOf(RespByte, 39);
    223. break;
    224. case 2: //驱动读卡器显示文字+蜂鸣响声+继电器开关+TTS语音
    225. DispBuf= DispStr.getBytes("gb2312"); //显示文字转字节数组
    226. String SpeakStr=""; //将要播报的TTS语音生成字节数组,最大不能超过126个字节
    227. SpeakStr="[v1]"; //定义语音大小,取值范围v0 到 v16,可加在任何地方
    228. SpeakStr=SpeakStr+"欢迎您使用我们的网络读卡器,谢谢!"; //要播报的中文语音
    229. byte[] SpeakBuf= SpeakStr.getBytes("gb2312");
    230. int SpeakLen=SpeakBuf.length; //语音长度
    231. int SendLen=11+34+SpeakLen+4; //总计发送数据长度
    232. RespByte[0]=(byte)0x5C; //指令码
    233. RespByte[1]=(byte)0x00; //机号低
    234. RespByte[2]=(byte)0x00; //机号高,如果高低位都为0表示任意机号
    235. RespByte[3]=(byte)0x01; //蜂鸣声代码
    236. RespByte[4]=(byte)0xF0; //继电器代码 F0表示全部继电器 F1表示1号继电器 F2表示2号继电器
    237. RespByte[5]=(byte)0x20; //继电器开启时长 低位
    238. RespByte[6]=(byte)0x00; //继电器开启时长 高位
    239. RespByte[7]=(byte)0x14; //显示保留时间,单位为秒,为0xFF时表示永久显示
    240. RespByte[8]=(byte)0x00; //在显示屏中的哪个位置开始
    241. RespByte[9]=(byte)0x22; //显示字符串长度 为全屏显示为 34 个字符
    242. RespByte[10]=(byte)SpeakLen; //语音长度
    243. for(int i=0;i<34;i++){ //显示的文字信息
    244. RespByte[i+11]=DispBuf[i];
    245. }
    246. for(int i=0;i//TTS语音播报信息
    247. RespByte[i+45]=SpeakBuf[i];
    248. }
    249. RespByte[10+34+SpeakLen+1]=(byte)0x55; //固定的抗干扰后缀
    250. RespByte[10+34+SpeakLen+2]=(byte)0xaa;
    251. RespByte[10+34+SpeakLen+3]=(byte)0x66;
    252. RespByte[10+34+SpeakLen+4]=(byte)0x99;
    253. RespByte = Arrays.copyOf(RespByte, 10+34+SpeakLen+5);
    254. break;
    255. case 3: //驱动读卡器开启继电器开关
    256. RespByte[0]=(byte)0x78; //指令码
    257. RespByte[1]=(byte)0x00; //机号低
    258. RespByte[2]=(byte)0x00; //机号高,如果高低位都为0表示任意机号
    259. RespByte[3]=(byte)0xF0; //继电器代码 F0表示全部继电器、F1表示1号继电器 、F2表示2号继电器......
    260. RespByte[4]=(byte)0x2C; //继电器开启延时低位
    261. RespByte[5]=(byte)0x01; //继电器开启延时高位,FFFF表示继电器一直开启
    262. RespByte = Arrays.copyOf(RespByte, 6);
    263. break;
    264. default:
    265. }
    266. return RespByte;
    267. }
    268. }

     

  • 相关阅读:
    重回童年4399| 【黄金矿工】游戏制作+解析
    【Arduino31】LED与步进电机实验
    2022年前端面试题整理,持续更新中
    ViT: Vision transformer的cls token作用?
    tkinter和Tkinter的区别
    MySQL进阶-sql执行时间的查询
    电视机顶盒哪个牌子好?拆机达人盘点网络电视机顶盒排名
    Python大数据之Python进阶(六)多线程的使用
    Hudi Spark源码学习总结-spark.read.format(“hudi“).load
    1019 数字黑洞
  • 原文地址:https://blog.csdn.net/zhangjin7422/article/details/134265839