java.nio.channels.ClosedChannelException问题主要出现在clientsMap.put(name,channel);该怎么解
藤虎的手 2014-05-09 10:32:40 package test7;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* @author kyle
*
*/
public class SelectSockets {
private static final int PORT_NUMBER = 7777;
private Charset cs = Charset.forName("gbk");
/*接受数据缓冲区*/
private ByteBuffer sBuffer = ByteBuffer.allocate(1024);
/*发送数据缓冲区*/
private ByteBuffer rBuffer = ByteBuffer.allocate(1024);
/*映射客户端channel */
private Map<String, SocketChannel> clientsMap = new HashMap<String, SocketChannel>();
private Selector selector;
/**
* @param args
*/
public static void main(String[] args) {
new SelectSockets().go(args);
}
private void go(String[] args) {
int port = PORT_NUMBER;
if (args.length > 0) {
try {
port = Integer.parseInt(args[0]);
} catch (Exception e) {
}
}
System.out.println("Listening port: " + PORT_NUMBER);
try {
Selector selector = Selector.open();
startServer(port, selector);
// public void run()
while (true) {
int n = selector.select();
if (n == 0) {
continue;
}
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
if (key.isAcceptable()) {
ServerSocketChannel server = (ServerSocketChannel) key
.channel();
SocketChannel channel = server.accept();
System.out.println("已连接...."+channel.socket().getLocalPort());
registerChannel(selector, channel, SelectionKey.OP_READ);
sayHello(channel);
}
if (key.isReadable()) {
int count = 0;
SocketChannel channel = (SocketChannel) key.channel();
buffer.clear();
while ((count = channel.read(buffer)) > 0) {
buffer.flip();
//while (buffer.hasRemaining()) {
String receiveText = String.valueOf(cs.decode(buffer).array());
System.out.println(receiveText);
dispatch(channel, receiveText);
//}
channel.register(selector, SelectionKey.OP_READ);
}
if (count < 0) {
channel.close();
System.out.println("断开。。。"+PORT_NUMBER);
}
}
}
it.remove();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private ByteBuffer buffer = ByteBuffer.allocate(1024);
public void dispatch(SocketChannel channel, String info) throws IOException {
// TODO Auto-generated method stub
Socket s = channel.socket();
String name = "["+s.getInetAddress().toString().substring(1)+":"+Integer.toHexString(channel.hashCode())+"]";
if(!clientsMap.isEmpty()){
for(Map.Entry<String, SocketChannel> entry : clientsMap.entrySet()){
SocketChannel temp = entry.getValue();
if(!channel.equals(temp)){
sBuffer.clear();
sBuffer.put(info.getBytes());
sBuffer.flip();
//输出到通道
temp.write(sBuffer);
}
}
}
//问题主要出在这一句上,用窜口模拟器测试连接,可以连接断开在发送消息不报closedchannelException异常;添加上
断开重连发送一条数据就会抛出closedchannelException;
clientsMap.put(name,channel);
}
private void sayHello(SocketChannel channel) throws IOException {
if (channel == null) {
return;
}
buffer.clear();
ByteBuffer buffer = ByteBuffer.wrap("Hi, there".getBytes());
buffer.flip();
channel.write(buffer);
}
private void registerChannel(Selector selector, SocketChannel channel,
int opRead) throws IOException {
if (channel == null) {
return;
}
channel.configureBlocking(false);
channel.register(selector, opRead);
}
private void startServer(int port, Selector selector) throws IOException,
ClosedChannelException {
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
ServerSocket serverSocket = serverChannel.socket();
serverSocket.bind(new InetSocketAddress(port));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
}
}
上面是服务端代码, //问题主要出在这一句上,用窜口模拟器测试连接,可以连接断开在发送消息不报closedchannelException异常;添加上
断开重连发送一条数据就会抛出closedchannelException;
clientsMap.put(name,channel);