示例使用的读卡器:RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
public class HttpServer_Java {
//监听端口
private static final int PORT = 88;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
Socket socket = null;
try {
//建立服务器的Socket,并设定一个监听的端口PORT
serverSocket = new ServerSocket(PORT);
//由于需要进行循环监听,因此获取消息的操作应放在一个while大循环中
while(true){
try {
//建立跟客户端的连接
socket = serverSocket.accept();
ServerThread thread = new ServerThread(socket);
thread.start();
} catch (Exception e) {
System.out.println("建立与客户端的连接出现异常");
e.printStackTrace();
}
//ServerThread thread = new ServerThread(socket);
//thread.start();
}
} catch (Exception e) {
System.out.println("端口被占用");
e.printStackTrace();
}
finally {
serverSocket.close();
}
}
}
//服务端线程类
//继承Thread类的话,必须重写run方法,在run方法中定义需要执行的任务。
class ServerThread extends Thread {
private Socket socket ;
InputStream inputStream;
OutputStream outputStream;
public ServerThread(Socket socket){
this.socket=socket;
}
public void run(){
try {
while (true){
//接收客户端的消息,解析信息并回应读卡器
//System.out.println(socket);
byte[] bytes =new byte[10240];
inputStream =socket.getInputStream();
int GetDataLen=0;
while ((GetDataLen=inputStream.read(bytes))!=-1){ //通过这个方法读取全部数据 及 长度,
break;
}
if(GetDataLen>0) {
String condition="";
String requestHeader= new String(bytes);
Date date=new Date();
SimpleDateFormat formatter=new SimpleDateFormat("yy-MM-dd HH:mm:ss.SSS");
String TimeStr=formatter.format(date);
System.out.println(TimeStr+" Received from " + socket.getRemoteSocketAddress() + " : " + requestHeader);
/*** 获得GET参数*/
if (requestHeader.startsWith("GET")) {
int begin = requestHeader.indexOf("?") + 1;
int end = requestHeader.indexOf("HTTP/");
condition = requestHeader.substring(begin, end);
}
else {
/*** 获得POST参数* 1.获取请求内容长度*/
if (requestHeader.startsWith("POST")) {
int begin = requestHeader.lastIndexOf("info") ;
condition = requestHeader.substring(begin).trim();
}
}
condition=condition.replace("{",""); //可以引用JSON的Jar包来解析json数据,这里将它转一般字符串来处理
condition=condition.replace("}","");
condition=condition.replace(",","&");
condition=condition.replace(":","=");
condition=condition.replace("\"","");
String ResponseStr=AnalyticHttpInfo(condition); //解析读卡器上传的包序号、卡号、机号等信息,并生成回应字符串
byte[] RespByte = ResponseStr.getBytes("gb2312");
outputStream = socket.getOutputStream();
outputStream.write(RespByte);
System.out.println(ResponseStr+'\n');
}
}
} catch (Exception e) {
System.out.println("客户端主动断开连接了");
e.printStackTrace();
}
//操作结束,关闭socket
try{
socket.close();
}catch(IOException e){
System.out.println("关闭连接出现异常");
e.printStackTrace();
}
}
/*-解析读卡器上传的包序号、机号、卡类型、卡号、卡内数据、设备序列号、读卡状态 等信息,并生成回应字符串------------------------------*/
static String AnalyticHttpInfo(String inputstr) throws Exception {
String info = "";
String jihao = "";
String cardtype = "";
String card = "";
String data = "";
String dn = "";
String status = "";
String heartbeattype = "";
String input = "";
String output = "";
String time = "";
String rand = "";
int typenum;
int pushortake = 0;
String[] strArr = inputstr.split("&");
for (int i = 0; i < strArr.length; i++) {
String[] strPara = strArr[i].split("=");
switch (strPara[0]) {
case "info":
info = strPara[1]; //接收到的数据包号,回应时要带入该包号才能正确回应
break;
case "jihao":
jihao = strPara[1]; //设备机号(可自编)
break;
case "cardtype":
cardtype = strPara[1];
typenum = (Integer.parseInt(cardtype, 16)) % 16; //卡类型,typenum=1为ID卡,2为HID卡,3为T5557卡,4为EM4305卡,5为IC卡,6为二代证,7为15693卡,8为hid iclass卡
pushortake = (Integer.parseInt(cardtype, 16)) / 128; //pushortake=0 表示读卡,>0表示卡离开感应区
break;
case "card":
card = strPara[1].trim(); //接收到的原始16进制卡号,可根据需要自行转换成其他卡号
break;
case "data":
data = strPara[1]; //读取卡片扇区内容
break;
case "dn":
dn = strPara[1].trim(); //设备硬件序列号,出厂时已固化,全球唯一
break;
case "status":
status = strPara[1]; //读卡状态,如密码认证失败为12
break;
case "heartbeattype":
heartbeattype = strPara[1]; //心跳包标志
break;
case "input":
input = strPara[1]; //输入接口状态
break;
case "output":
output = strPara[1]; //输出接口状态
break;
case "time":
time = strPara[1]; //设备时钟
break;
case "rand":
rand = strPara[1]; //随机数
break;
}
}
if (heartbeattype.equals("1") && dn.length() == 16 && info.length() > 0) { //接收到心跳包
//return "Response=1," + info + ",,0,0," ;
String DisplayStr = dn + GetChineseCode("接收到心跳信息! "); //正式项目可以用不显示文字、不响声、不播报语音的指令来回应心跳,此处加入显示、响声只是用来检测读卡器功能
return "Response=1," + info + "," + DisplayStr + ",20,2,";
} else if (dn.length() == 16 && card.length() > 4 && info.length() > 0) { //接收到刷卡信息
String DisplayStr = "{" + GetChineseCode("卡号") + ":}"; //发送到读卡器上显示的文字,中文要转换编码,英文、数字可以不需要转换,{}中的文字可以高亮显示
DisplayStr = DisplayStr + (card + " ").substring(0, 12) + GetSysDT();
String ChineseVoice = "[v1]"; //[v1] 表示本次播报的语音量,取值范围 v1 到 v16
if (pushortake > 0) {
ChineseVoice = ChineseVoice + GetChineseCode("卡号") + "[n1]" + card + GetChineseCode("离开感应区!"); //发送到读卡器上播报的TTS中文语音,所有中文要转换编码,英文、数字可以不需要转换,[n1]表示数字播方方式
} else {
ChineseVoice = ChineseVoice + GetChineseCode("读取卡号") + "[n1]" + card;
}
//Response=1 是指定的回应头信息+接收到的包序号+发送到读卡器的显示文字,+显示延时秒数+蜂鸣响声代码+播报的TTS语音
return "Response=1," + info + "," + DisplayStr + ",20,2," + ChineseVoice;
}else{
return "Response=1,"; //其他未知的消息
}
}
/*取电脑系统日期时间-------------------------------------------------------------------------------------------------*/
static String GetSysDT() {
Date date=new Date();
SimpleDateFormat formatter=new SimpleDateFormat("yy-MM-dd HH:mm:ss");
String TimeStr=formatter.format(date);
return TimeStr;
}
/*获取中文编码信息----------------------------------------------------------------------------------------------*/
static String GetChineseCode(String inputstr) throws Exception{
int strlen=inputstr.length();
String hexcode="";
for (int j=0;j<strlen;j++) {
String str=inputstr.substring(j,j+1);
byte[] Chinesecodearry = str.getBytes("gb2312");
int codelen=Chinesecodearry.length;
if(codelen==1){
hexcode=hexcode+str;
}else{
hexcode=hexcode+"\\x";
for (int i=0;i<codelen;i++) {
String bytestr="00"+Integer.toHexString(Chinesecodearry[i] & 0xff);
hexcode=hexcode+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
}
}
return hexcode;
}
}