SocketChannel客户端程序编写
最近我在做一个读卡器项目,采用的是java语言开发。出现了一点问题,请大家帮我看一下。
需求:1.采用的事socket通信。厂家说在通信过程中需要有一个监听器监听缓冲区有数据,就接收数据,分析数据, 进行下次接收。
2发送登录命令 :AC 02 00 08 00 21 40 23 23 CD CE 0D ED。
3.登录成功后,读卡器会每隔五秒发送一次正常心跳。而我的程序需要发送确认收到心跳的命令:AC 10 DA 00 00 00,
4.但同时,如果有人刷卡,读卡器会发送卡信息给程序。也需要确认。如果卡信息不确认会丢失。
厂家给的测试程序采用的是C#开发,这一块实现原理首先是接收数据,如果接收到数据,就中断连接,分析数据,看数据是正常连接心跳,还是卡事件心跳,然后向读卡器发送确认指令AC 10 DA 00 00 00,分析完之后才可以进行下次数据接收。
我的程序是这样写的,总是获取不到卡号。实时的获取不到卡号。我写的一个测试程序。
最后我确认以后是SocketChannel编程。但是我真不知道如何实现我的业务需求,所以从网上找了代码,改了一下,但是达不到我的业务需求,请帮我看一下。
以下是我写的代码:帮忙看一下,谢谢了
客户端类:
package nio;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
/**
* 客户端程序
* @author Administrator
*
*/
public class TCPClinet {
private Selector selector;
SocketChannel channel;
private String ip;
private int port;
public TCPClinet(String ip,int port) throws Exception{
this.ip = ip;
this.port = port;
//sendCmd();
init();
}
public void init() throws Exception{
channel = SocketChannel.open(new InetSocketAddress(ip, port));
channel.configureBlocking(false);
selector = Selector.open();
channel.register(selector, SelectionKey.OP_READ);
new TCPClientReadThread(selector);
}
/**
* 发送byte[]数组到读卡器
* @throws Exception
*/
public void sendCmd() throws Exception{
int[] cmd = {0xAC, 0x02, 0x00, 0x08, 0x00, 0x21, 0x40, 0x23, 0x23,
0xCD, 0xCE, 0x0D, 0xED, 0xAC, 0x01, 0x00, 0x00, 0x00 };
byte[] b = new byte[cmd.length];
for(int i = 0;i< b.length;i++){
b[i] = (byte)cmd[i];
}
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.write(buffer);
}
public static void main(String[] args) {
try {
TCPClinet tcp = new TCPClinet("192.168.14.243", 6655);
tcp.sendCmd();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端线程类:
package nio;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class TCPClientReadThread implements Runnable {
// 监听器,如果缓冲区有数据,通知程序接收
private Selector selector;
public TCPClientReadThread(Selector selector) {
this.selector = selector;
new Thread(this).start();
}
@Override
public void run() {
try {
while (selector.select() > 0) {
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iter = keys.iterator();
while (iter.hasNext()) {
SelectionKey key = (SelectionKey) iter.next();
iter.remove();
System.out.println(selector.keys().size());
if (key.isReadable()) {
SocketChannel socketChannel = (SocketChannel) key
.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int byteRead = socketChannel.read(buffer);
buffer.clear();
if (byteRead == -1) {
socketChannel.close();
} else {
buffer.flip();
byte[] content = new byte[buffer.limit()];
// 从ByteBuffer中读取数据到byte数组中
buffer.get(content);
String receivedString = btyetoString(content);
// String receivedString =
// Charset.forName("UTF-16").newDecoder().decode(buffer).toString();
System.out.println("接收到来自服务器"
+ socketChannel.socket()
.getRemoteSocketAddress() + "的信息:"
+ receivedString);
// 发送确认命令给服务器
int[] cmds = { 0xAC, 0x10, 0xDA, 0x00, 0x00 };
byte[] bb = new byte[cmds.length];
for (int i = 0; i < bb.length; i++) {
bb[i] = (byte) cmds[i];
}
// buffer.get(bb);
socketChannel.write(buffer);
key.interestOps(SelectionKey.OP_READ
| SelectionKey.OP_WRITE);
}
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static final String btyetoString(byte[] bArray) {
StringBuffer sb = new StringBuffer(bArray.length);
String sTemp;
for (int i = 0; i < bArray.length; i++) {
sTemp = Integer.toHexString(0xFF & bArray[i]);
if (sTemp.length() == 1) {
sb.append(0);
}
sb.append(sTemp.toUpperCase());
sb.append(" ");
}
return sb.toString();
}
}