iteye_12241 2011-03-26 18:36
浏览 261
已采纳

非阻塞通信的问题

运行服务器后,在运行客户端,
服务器就挂了,
然后客户端一直循环显示
客户端可读...
客户端可写...
客户端可读...
客户端可写...
客户端可读...
客户端可写...

服务器端显示
Serve 启动了!
服务器端接收到连接...
Exception in thread "main" 客户端信息/192.168.1.76:4634
java.nio.channels.IllegalBlockingModeException
at java.nio.channels.spi.AbstractSelectableChannel.register(Unknown Source)
at nonblock.MyServer.server(MyServer.java:40)
at nonblock.MyServer.main(MyServer.java:55)

请问这是怎么回事啊?
谢谢了啊

这个是服务器端的代码
[code="java"]package nonblock;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;
import java.util.*;

public class MyServer {

private ServerSocketChannel ssc ;
private Selector selector ;
private int port = 8000;
private Charset charset ;

public MyServer() throws IOException{
    selector = Selector.open();
    ssc = ServerSocketChannel.open();
    ssc.socket().setReuseAddress(true);
    ssc.configureBlocking(false);
    ssc.socket().bind(new InetSocketAddress(port));
    System.out.println("Serve 启动了!");
}

public void server() throws IOException{
    ssc.register(selector, SelectionKey.OP_ACCEPT);
    while(selector.select()>0){
        Set keySet = selector.selectedKeys();
        Iterator iter = keySet.iterator();
        while(iter.hasNext()){
            SelectionKey key = (SelectionKey)iter.next();
            //一定要remove,否则会一直存在
            iter.remove();
            if(key.isAcceptable()){
                ServerSocketChannel s = (ServerSocketChannel)key.channel();
                SocketChannel sc = (SocketChannel)s.accept();
                System.out.println("服务器端接收到连接...");
                System.out.println("客户端信息"+sc.socket().getLocalAddress()+":"+sc.socket().getPort());
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                sc.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE, buffer);
                System.out.println("服务器完成注册...");
            }
            if(key.isReadable()){
                System.out.println("服务器端可以读取信息...");
            }
            if(key.isWritable()){
                System.out.println("服务器端可以写入信息...");
            }
        }
    }
}

public static void main(String[] arg){
    try {
        new MyServer().server();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}
[/code]

这个是客户端的代码
[code="java"]package nonblock;
import java.net.*;
import java.nio.channels.*;
import java.nio.*;
import java.io.*;
import java.nio.charset.*;
import java.util.*;

public class MyClient {
private SocketChannel socketChannel = null;
private ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
private ByteBuffer receiveBuffer = ByteBuffer.allocate(1024);
private Charset charset = Charset.forName("GBK");
private Selector selector;

public MyClient() throws IOException {
    socketChannel = SocketChannel.open();
    InetAddress ia = InetAddress.getLocalHost();
    InetSocketAddress isa = new InetSocketAddress(ia, 7676);
    socketChannel.connect(isa);
    socketChannel.configureBlocking(false);
    System.out.println("与服务器的连接建立成功");
    selector = Selector.open();
}

public static void main(String args[]) throws IOException {
    final MyClient client = new MyClient();

// Thread receiver = new Thread() {
// public void run() {
// client.receiveFromUser();
// }
// };
//
// receiver.start();
client.talk();
}

private void talk() throws IOException {
    // TODO Auto-generated method stub
    socketChannel.register(selector, SelectionKey.OP_READ
            | SelectionKey.OP_WRITE);
    while(selector.select()>0){
        Set keySet = selector.selectedKeys();
        Iterator iter = keySet.iterator();
        while(iter.hasNext()){
            SelectionKey key = (SelectionKey)iter.next();
            iter.remove();

            if(key.isReadable()){
                System.out.println("客户端可读...");
            }
            if(key.isWritable()){
                System.out.println("客户端可写...");
            }
        }

    }

}

}
[/code]

  • 写回答

1条回答 默认 最新

  • shadabing 2011-03-27 23:11
    关注

    1 第一首先你的服务器监听8000端口,那么你肯定去连接8000端口,而不是7676
    2 SocketChannel sc = (SocketChannel)s.accept();

    System.out.println("服务器端接收到连接...");

    System.out.println("客户端信息"+sc.socket().getLocalAddress()+":"+sc.socket().getPort());

    ByteBuffer buffer = ByteBuffer.allocate(1024);

    sc.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE)
    这段代码SocketChannel默认是阻塞式的,你想注册为非阻塞式的,可定需要设置
    sc.configureBlocking(false);

    3客户端既然是非阻塞式连接,当然需要对连接是否成功的判断

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办