Nio本地测试,多线程客户端连接,出现部分线程无返回

mdxk 2009-09-08 09:12:57
参照nio示例书写,最简单的测试,客户端使用socket多线程连接通信,总是出现部分线程没有收到返回数据,然后导致通信阻塞,CPU全满。请教原因。全部返回出现的原因就是客户端线程sleep时间多一些。
---------------------------------------------------------------------------------
服务端
public class NioMonitor extends Thread {
private Selector selector = null;
private ServerSocketChannel srvChannel = null;
private ServerSocket srvSocket = null;
private ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 50, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
private int _port = 0;

public NioMonitor(int port) {
this._port = port;
}

public void initializeOperations() throws IOException {
// 创建服务端Socket
srvChannel = ServerSocketChannel.open();
// 设置成非阻塞模式
srvChannel.configureBlocking(false);
// 绑定主机端口
srvSocket = srvChannel.socket();
srvSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), _port));
// 创建一个监视器Selector对象
selector = Selector.open();
// 注册接受端口
srvChannel.register(selector, SelectionKey.OP_ACCEPT);
}

private boolean run = true;

public void run() {
// 初期化服务
try {
initializeOperations();
} catch (Exception e) {
e.printStackTrace();
return;
}

// 开始服务循环
while (run) {
try {
int num = 0; // 等待事件
num = selector.select(1);
// 判断事件激活
if (num == 0) {
continue; // nothing to do
}
// 获得关键字标识
// Set<SelectionKey> keys
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
// 遍历,对每个关键字处理
while (it.hasNext()) {
SelectionKey key = it.next();
if (key.isValid()) {
handleConnection(key);
} else {
cancelKey(key);
}// if isValid
}// while it.hasNext
} catch (Exception e) {
continue;
}
}
}

public void cancelKey(SelectionKey key) throws IOException, InterruptedException {
// 关闭
key.cancel();
}

public void handleConnection(SelectionKey key) throws IOException, InterruptedException {
// 如果可以访问,客户端请求一个连接
if (key.isAcceptable()) { // 取出对应的服务器通道
SocketChannel clientChannel = srvChannel.accept();
// 处理连接
if (clientChannel.finishConnect()) {
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
} else {
return;
}
}
SocketChannel clientChannel = (SocketChannel) key.channel();
// 测试此键的通道是否已准备好进行读取。
if (key.isReadable()) {
ByteBuffer clientBuffer = ByteBuffer.allocate(256);
clientBuffer.clear();
// 从通道中读数据到缓冲中,返回读取得字节数
while ((clientChannel.read(clientBuffer)) > 0) {
clientBuffer.flip();
}
CharBuffer charBuffer = NioCharset.getInstance().getDecoder().decode(clientBuffer);
// 读取的数据
String name = charBuffer.toString();
System.out.println("read:===" + name);
clientBuffer = NioCharset.getInstance().getEncoder().encode(CharBuffer.wrap(name));
// 写入数据对象
while (clientBuffer.hasRemaining()) {
clientChannel.write(clientBuffer);
}
clientBuffer.clear();
// 关闭连接
clientChannel.close();
key.cancel();
} else {
cancelKey(key);
}
}
}
--------------------------------------------------------
连接代码
ublic class SocketClientThread extends Thread{
private Socket clinetSocket_;
private BufferedInputStream in_;
private BufferedOutputStream out_;

private InetAddress serverIP_ = null;
private int serverPort_ = 0;

public SocketClientThread(InetAddress hostIP, int port) throws Exception {
this(hostIP, port, 2000);
}

public SocketClientThread(InetAddress hostIP, int port, int time) throws Exception {
serverIP_ = hostIP;
serverPort_ = port;
clinetSocket_ = new Socket();
clinetSocket_.connect(new InetSocketAddress(serverIP_, serverPort_), time);
out_ = new BufferedOutputStream(clinetSocket_.getOutputStream());
}

private int size_ = 256;
private byte[] dataStream_ = null;

public void run() {
try {
this.sleep(1000);
String in="asdf";
// 发送数据
out_.write(in.getBytes());
System.out.println(new String(in.getBytes()));
out_.flush();

// 接收数据
dataStream_ = new byte[size_];
in_ = new BufferedInputStream(clinetSocket_.getInputStream());
int length = in_.read(dataStream_);

System.out.println("out==="+new String(dataStream_));

this.isInterrupted();

} catch (Exception e) {
e.printStackTrace();
}
}
}
-----------------------------------------
测试代码
NioMonitor nm = new NioMonitor(12345);
nm.start(); try{
for(int i=0;i<5;i++){
try{
SocketClientThread ct = new SocketClientThread(InetAddress.getLocalHost(),12345);
ct.start();
}catch(Exception e){
e.printStackTrace();
}
}}
catch(Exception xe){
xe.printStackTrace();
}
...全文
114 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧