JAVA NIO服务器:如何重置所有连接
我必须在JBoss中构建一个JavaNIO服务器应用程序,以便从10-200个传感器盒中读取数据。他们打开一个流,一直向我发送数据。通信是双向的。现在,有时会发生这样的情况:这些盒子(或服务器)有一些内部错误。为了检测这类问题,观察者线程每5秒检查一次数据块是否在上次检查后进入。如果在此之前我的任何一个盒子都没有发送数据,那么就发生了不好的事情,我想重新启动整个套接字通信 现在,关于如何使用NIO建立套接字连接已经有了很好的文档记录,但是很难找到如何清理和重置它们的复杂示例。这就是我的问题:当我的看门狗检测到在过去5秒内没有数据时,它会调用close()然后调用startEngine()。但在那之后,仍然没有数据到达。有些东西似乎被阻塞了,有些资源仍然相关或类似。如果我重新启动JBoss,数据就会再次到达。谁能给我一个提示吗 谢谢你抽出时间! 斯特凡JAVA NIO服务器:如何重置所有连接,java,sockets,nio,Java,Sockets,Nio,我必须在JBoss中构建一个JavaNIO服务器应用程序,以便从10-200个传感器盒中读取数据。他们打开一个流,一直向我发送数据。通信是双向的。现在,有时会发生这样的情况:这些盒子(或服务器)有一些内部错误。为了检测这类问题,观察者线程每5秒检查一次数据块是否在上次检查后进入。如果在此之前我的任何一个盒子都没有发送数据,那么就发生了不好的事情,我想重新启动整个套接字通信 现在,关于如何使用NIO建立套接字连接已经有了很好的文档记录,但是很难找到如何清理和重置它们的复杂示例。这就是我的问题:当我
公共类TestServer
{
专用NIOServer;
private HashMap clientsList=new HashMap();
类NIOServer扩展线程
{
类消息缓冲区
{
int[]msgAsByte=新int[msgSize];
int pos=0;
int lastSign=0;
int字节读取=0;
}
private ByteBuffer readBuffer=ByteBuffer.allocate(256);
专用选择器;
私有布尔停止=false;
专用int[]端口;
私有int-msgSize=48;
私有HashMap缓冲区=新HashMap();
私人列表频道;
//将SocketChannel映射到ByteBuffer实例列表
私有映射pendingDataToWrite=newHashMap();
公共NIOServer(int[]端口){
这个端口=端口;
}
私有void stopAll()
{
停止=真;
尝试
{
中断();
加入服务器(3000);
}
捕捉(中断异常e){
Thread.currentThread().interrupt();
}
闭合连接();
}
public void sendData(SocketChannel套接字,字节[]数据)
{
//并将要写入的数据排队
已同步(此.pendingDataToWrite){
列表队列=(列表)this.pendingDataToWrite.get(套接字);
if(队列==null){
queue=newarraylist();
this.pendingDataToWrite.put(套接字,队列);
}
add(ByteBuffer.wrap(数据));
}
SelectionKey=socket.keyFor(此.selector);
if(key!=null)
key.interesttops(选择key.OP_WRITE);
//最后,唤醒我们正在选择的线程,以便它可以进行所需的更改
这个.selector.wakeup();
}
公开募捐
{
尝试
{
停止=错误;
选择器=selector.open();
通道=新的ArrayList();
serversocketchannelserverchannel;
用于(int端口:端口)
{
尝试
{
serverchannel=ServerSocketChannel.open();
serverchannel.configureBlocking(false);
尝试
{
serverchannel.socket().setReuseAddress(true);
}
捕获(SocketException se)
{
//
}
serverchannel.socket().bind(新的InetSocketAddress(端口));
serverchannel.register(选择器、SelectionKey.OP_ACCEPT);
channels.add(serverchannel);
}
捕获(例外e)
{
//
}
}
当(!停止)
{
SelectionKey=null;
尝试
{
selector.select();
迭代器键迭代器=选择器。selectedKeys()
.iterator();
while(keysIterator.hasNext())
{
key=keysIterator.next();
if(key.isValid())
{
if(key.isAcceptable())
{
接受(钥匙);
}
else if(key.isReadable())
{
读取数据(键);
}
else if(key.isWritable())
{
写入数据(键);
}
}
其他的
{
SocketChannel sc=(SocketChannel)key.channel();
}
键位
public class TestServer
{
private NIOServer server;
private HashMap<String, SocketChannel> clientsList = new HashMap<String, SocketChannel>();
class NIOServer extends Thread
{
class MessageBuffer
{
int [] msgAsByte = new int[msgSize];
int pos = 0;
int lastSign = 0;
int bytesRead = 0;
}
private ByteBuffer readBuffer = ByteBuffer.allocate(256);
private Selector selector;
private boolean stop = false;
private int[] ports;
private int msgSize = 48;
private HashMap<String,MessageBuffer> buffer = new HashMap<String, MessageBuffer>();
private List<ServerSocketChannel> channels;
// Maps a SocketChannel to a list of ByteBuffer instances
private Map<SocketChannel, List<ByteBuffer>> pendingDataToWrite = new HashMap<SocketChannel, List<ByteBuffer>>();
public NIOServer(int[] ports) {
this.ports = ports;
}
private void stopAll()
{
stop = true;
try
{
server.interrupt();
server.join(3000);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
closeConnections();
}
public void sendData(SocketChannel socket, byte[] data)
{
// And queue the data we want written
synchronized (this.pendingDataToWrite) {
List<ByteBuffer> queue = (List<ByteBuffer>) this.pendingDataToWrite.get(socket);
if (queue == null) {
queue = new ArrayList<ByteBuffer>();
this.pendingDataToWrite.put(socket, queue);
}
queue.add(ByteBuffer.wrap(data));
}
SelectionKey key = socket.keyFor(this.selector);
if(key != null)
key.interestOps(SelectionKey.OP_WRITE);
// Finally, wake up our selecting thread so it can make the required changes
this.selector.wakeup();
}
public void run()
{
try
{
stop = false;
selector = Selector.open();
channels = new ArrayList<ServerSocketChannel>();
ServerSocketChannel serverchannel;
for (int port : ports)
{
try
{
serverchannel = ServerSocketChannel.open();
serverchannel.configureBlocking(false);
try
{
serverchannel.socket().setReuseAddress(true);
}
catch(SocketException se)
{
//
}
serverchannel.socket().bind(new InetSocketAddress(port));
serverchannel.register(selector, SelectionKey.OP_ACCEPT);
channels.add(serverchannel);
}
catch(Exception e)
{
//
}
}
while (!stop)
{
SelectionKey key = null;
try
{
selector.select();
Iterator<SelectionKey> keysIterator = selector.selectedKeys()
.iterator();
while (keysIterator.hasNext())
{
key = keysIterator.next();
if(key.isValid())
{
if (key.isAcceptable())
{
accept(key);
}
else if (key.isReadable())
{
readData(key);
}
else if (key.isWritable())
{
writeData(key);
}
}
else
{
SocketChannel sc = (SocketChannel) key.channel();
}
keysIterator.remove();
}
}
catch ( Exception e)
{
if(e instanceof IOException || e instanceof ClosedSelectorException)
{
try
{
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
channels.remove(ssc);
ssc.close();
key.cancel();
}
catch(Exception ex)
{
//
}
}
else
{
//
}
}
}
}
catch(Exception e1)
{
//
}
closeConnections();
}
private void closeConnections()
{
//if thread is stopped, close all
try
{
try
{
if(this.selector == null || this.selector.keys() == null)
{
log.debug("No selectors or keys found to close");
}
else
{
Iterator<SelectionKey> keys = this.selector.keys().iterator();
while(keys.hasNext())
{
SelectionKey key = keys.next();
key.cancel();
}
}
}
catch(Exception ex) {
//
}
if(selector != null)
selector.close();
if(channels != null)
{
for(ServerSocketChannel channel:channels)
{
channel.socket().close();
channel.close();
}
}
if(clientsList != null)
{
Iterator<Map.Entry<String, SocketChannel>> hfm = clientsList.entrySet().iterator();
while(hfm.hasNext())
{
Map.Entry<String, SocketChannel> s = hfm.next();
s.getValue().close();
}
}
clientsList=null;
selector = null;
channels = null;
pendingDataToWrite = null;
}
catch(Exception e)
{
//
}
}
private void accept(SelectionKey key) throws IOException
{
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
String ip = sc.socket().getRemoteSocketAddress().toString();
if(!buffer.containsKey(ip))
buffer.put(ip, new MessageBuffer());
}
private void readData(SelectionKey key) throws Exception
{
SocketChannel sc = (SocketChannel) key.channel();
MessageBuffer buf = buffer.get(sc.socket().getRemoteSocketAddress().toString());
try
{
buf.bytesRead = sc.read(readBuffer); //read into buffer.
}
catch(Exception e2)
{
sc.close();
buffer.remove(sc);
}
//close connection
if (buf.bytesRead == -1)
{
sc.close();
key.cancel();
return;
}
readBuffer.flip(); //make buffer ready for read
while(readBuffer.hasRemaining())
{
//Read the data and forward it to another Process...
}
readBuffer.compact(); //make buffer ready for writing
}
private void writeData(SelectionKey key) throws Exception
{
SocketChannel socketChannel = (SocketChannel) key.channel();
synchronized (this.pendingDataToWrite) {
List queue = (List) this.pendingDataToWrite.get(socketChannel);
// Write until there's not more data ...
while (!queue.isEmpty()) {
ByteBuffer buf = (ByteBuffer) queue.get(0);
try
{
socketChannel.write(buf);
}
catch(Exception e)
{
//
}
finally
{
queue.remove(0);
}
if (buf.remaining() > 0) {
// ... or the socket's buffer fills up
break;
}
}
key.interestOps(SelectionKey.OP_READ);
}
}
}
public void close() {
if (server != null && server.isAlive())
{
server.stopAll();
}
if(clientsList != null)
{
clientsList.clear();
}
server = null;
}
public void startEngine(int[] ports) {
if (ports != null) {
for (int port : ports)
log.info("Listening on port " + port);
server= new NIOServer(ports);
server.start();
}
}
}