`
AAries
  • 浏览: 39720 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

SocketChannel使用心得

 
阅读更多
1.服务器端while(true) 一直等待client端来连接。
  基本步骤为:
        ServerSocketChannel server = ServerSocketChannel.open();
        server.configureBlocking(false);

        server.socket().bind(new InetSocketAddress(5200));

        Selector select = Selector.open();
        server.register(select, SelectionKey.OP_ACCEPT);


声明一个等待客户端的服务器。
     select.select();
            Set readkeys = select.selectedKeys();
            Iterator iterator = readkeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = (SelectionKey) iterator.next();
                if (key.isAcceptable()) {
                    SocketChannel client = ((ServerSocketChannel) key.channel()).accept();
                    System.out.println("Accept connection from: " + client);
                    client.configureBlocking(false);
                    client.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                }
                if (key.isReadable()) {

                    // 获得与客户端通信的信道
                    SocketChannel clientChannel = (SocketChannel) key.channel();

                    // 得到并清空缓冲区
                    ByteBuffer buffer = (ByteBuffer) key.attachment();
                    buffer.clear();

                    // 读取信息获得读取的字节数
                    long bytesRead = clientChannel.read(buffer);

                    if (bytesRead == -1) {
                        // 没有读取到内容的情况
                        clientChannel.close();
                    } else {
                        // 将缓冲区准备为数据传出状态
                        buffer.flip();

                        // 将字节转化为为UTF-16的字符串   
                        String receivedString = Charset.forName("UTF-16").newDecoder().decode(buffer).toString();

                        // 控制台打印出来
                        System.out.println("接收到来自" + clientChannel.socket().getRemoteSocketAddress() + "的信息:" + receivedString);

                        // 准备发送的文本
                        String sendString = "你好,客户端. @" + new Date().toString() + ",已经收到你的信息" + receivedString;
                        buffer = ByteBuffer.wrap(sendString.getBytes("UTF-16"));
                        clientChannel.write(buffer);

                        // 设置为下一次读取或是写入做准备
                        key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                    }
                }
                if (key.isWritable())
                {
                    SocketChannel sc = (SocketChannel) key.channel();
                    ByteBuffer writeBuffer=ByteBuffer.wrap("我的程序员之道".getBytes("UTF-16"));
                    sc.write(writeBuffer);
                }
                key.channel().close();
            }

遍历键集,然后判断键的可读可写等做不同的操作

客户端建立一个线程,等待服务器端的回应:
1.建立基本的SocketChannel
       SocketChannel sc = SocketChannel.open(new InetSocketAddress("172.16.22.11", 5200));
        //打开一个SocketChannel并连接到服务器
        sc.configureBlocking(false);

        Selector selector = Selector.open();

        sc.register(selector, SelectionKey.OP_READ);


在实现Runable的run方法里遍历键集,判断做不同的操作:
while (selector.select() > 0) {
                // 遍历每个有可用IO操作Channel对应的SelectionKey
                Iterator it = selector.selectedKeys().iterator();
                while (it.hasNext()) {
                    SelectionKey sk = (SelectionKey) it.next();
                    it.remove();
                    // 如果该SelectionKey对应的Channel中有可读的数据
                    if (sk.isReadable()) {
                        // 使用NIO读取Channel中的数据
                        SocketChannel socketChannel = (SocketChannel) sk.channel();

                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        socketChannel.read(buffer);
                        buffer.flip();

                        // 将字节转化为为UTF-16的字符串   
                        String receivedString = Charset.forName("UTF-16").newDecoder().decode(buffer).toString();

                        // 控制台打印出来
                        System.out.println("接收到来自服务器" + socketChannel.socket().getRemoteSocketAddress() + "的信息:" + receivedString);

                        // 为下一次读取作准备
//                        sk.interestOps(SelectionKey.OP_READ);//将键设为可读

                    }
                    if (sk.isWritable()) {
                        SocketChannel socketChannel = (SocketChannel) sk.channel();
                        ByteBuffer writeBuffer = ByteBuffer.wrap("我的程序员之道".getBytes("UTF-16"));
                        socketChannel.write(writeBuffer);
                    }

                    // 删除正在处理的SelectionKey
                    selector.selectedKeys().remove(sk);
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
分享到:
评论
1 楼 kingj 2012-02-23  
你好,这个程序好像有问题,在我的windows xp上面跑不起来

相关推荐

    java的ServerSocketChannel与SocketChannel的使用

    使用`ServerSocketChannel`,我们可以设置监听指定的端口,并在有新的连接请求时,通过调用`accept()`方法来接受连接并返回一个新的`SocketChannel`对象,这个`SocketChannel`代表了与客户端建立的具体连接。...

    tcp.rar_SocketChannel_SocketChannel HTTPS_java socketchannel_非阻

    4. 使用SocketFactory创建一个`SSLSocketChannel`,并将其与普通的SocketChannel关联起来。 5. 初始化SSL会话,包括握手过程,这可能涉及到多次读写操作,直到握手成功。 6. 在会话建立后,就可以使用非阻塞的`read...

    java SocketChannel通信实例

    2. 打开SocketChannel:使用ServerSocketChannel.bind()方法监听指定端口,然后调用accept()方法获取连接的SocketChannel。 3. 注册Selector:使用SocketChannel的register()方法,将通道注册到Selector上,同时指定...

    SocketChannel、ServerSocketChannel与Selector的实际案例

    与传统的Socket相比,SocketChannel允许我们在读写操作上使用非阻塞模式,从而提高程序的并发性能。 2. **ServerSocketChannel**:这个类代表了一个服务器端的套接字,用于监听客户端的连接请求。创建...

    使用非阻塞ServerSocketChannel、SocketChannel代替ServerSocket和Socket

    本篇文章将详细解析如何使用非阻塞ServerSocketChannel和SocketChannel来替代传统的ServerSocket和Socket。 **1. 阻塞与非阻塞I/O** 在阻塞I/O模型中,当一个线程调用read或write方法时,如果数据没有准备好或者...

    ProxiedSocketChannel:一个 Java SocketChannel 实现,它使用提供的 Proxy 实例通过提供的代理建立网络连接

    一个 Java SocketChannel 实现,它使用提供的 Proxy 实例通过提供的代理建立网络连接。 SocketChannel 是通过表面下的 Socket 实例实现的。 限制 此实现目前仅支持阻塞模式。 请注意,这是 SocketChannel 实例的默认...

    niossl:SSLSocketChannel和SSLServerSocketChannel实现

    NIO SSL 与阻塞IO不同,JVM不提供扩展基本套接字通道类的标准SSLSocketChannel和SSLServerSocketChannel类。 相反,必须使用手动编排SSL交换。...使用SSLSocketChannel 由普通的SocketChannel和必要的SSL相关信息

    【IT十八掌徐培成】Java基础第27天-02.NIO-ServerSocketChannel-SocketChannel.zip

    通过使用Selector,我们可以设计出一种选择器模式,将多个通道注册到同一个选择器上,然后在单个线程中轮询选择器,处理那些准备好的通道,从而实现高并发的网络服务。 总的来说,本教程将围绕ServerSocketChannel...

    java多路复用socket客户端.

    使用socket channel 连接服务器,断线重连,发送保活等的封装类。 Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel: 打开一个SocketChannel并连接到互联网上的...

    基于SocketChannel的即时聊天程序

    没有使用其他jar包 主要功能: 1、广场群聊,即发送的消息所有在线的人都能看到 2、聊天室群聊,可以创建聊天室,进入聊天室的人可以在里面聊天,创建的人或者是第一个人为管理员,拥有踢人的权限;广场上有一个...

    高级 socket 通信

    本主题聚焦于“高级Socket通信”,特别是涉及到使用SocketChannel的实现方式。SocketChannel是Java NIO(非阻塞I/O)框架的一部分,它提供了一种更高效、灵活的方式来处理网络连接。 首先,我们要理解Socket的基本...

    java nio Selector的使用-客户端

    SocketChannel socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); // 连接到服务器 InetSocketAddress serverAddress = new InetSocketAddress("localhost", 8080); ...

    Android开发进阶之NIO非阻塞包

    - **读取数据**:使用`socketChannel.read(ByteBuffer buffer)`从SocketChannel中读取数据。 - **发送数据**:使用`socketChannel.write(ByteBuffer buffer)`向SocketChannel中写入数据。 2. **ByteBuffer**:它...

    Socket实现聊天室功能

    在这个案例中,我们将讨论如何使用Socket来实现一个简单的聊天室功能,包括服务器端和客户端的实现。 首先,我们要理解Socket的基本概念。Socket是网络通信中的一个抽象接口,可以看作是两台计算机之间的通信通道。...

    libgdx net的使用

    - 当有客户端连接时,创建一个新的`SocketChannel`来处理该连接上的通信。 ```java NioServerSocketChannel server = NioServerSocketChannel.open(); server.bind(new InetSocketAddress("localhost", 4444)); ...

    JAVA nio的一个简单的例子

    客户端通常使用SocketChannel与服务器建立连接,并通过该通道发送和接收数据。在发送数据前,需要先将数据写入Buffer,然后调用`SocketChannel.write()`方法。接收到服务器响应后,使用`SocketChannel.read()`读取...

    实现java网络与nio例子

    - 客户端首先需要创建一个SocketChannel,通过`SocketChannel.open()`打开,并使用`SocketChannel.connect(SocketAddress)`连接到服务器端的地址。 - 同样,客户端也需要使用缓冲区进行数据的读写操作。 - 如果...

    java 聊天代码 9

    - 使用 `SocketChannel` 进行网络通信。 - 设置目标服务器地址和端口。 - 尝试建立非阻塞连接。 - 发送用户名到服务器。 #### 3. `inputName` 方法 - 使用 `JOptionPane.showInputDialog` 获取用户的输入,并设置为...

    java-nio.rar_NIO_java nio

    它们分别展示了如何使用`SocketChannel`实现客户端和服务器端的非阻塞IO通信。 在`SocketChannelClient.java`中,客户端通常会首先创建一个`SocketChannel`,然后打开一个连接到服务器的通道。接着,它会创建一个`...

Global site tag (gtag.js) - Google Analytics