博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ServerSocketChannel和SocketChannel
阅读量:5359 次
发布时间:2019-06-15

本文共 5538 字,大约阅读时间需要 18 分钟。

暂未考虑花大时间去学这些底层代码,直接进入框架的学习,代码来自网络

 

Server

package spring.server;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;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.Iterator;public class Server {    /*     * 处理器类     */    static class Handler {        private int bufferSize = 1024; // 缓冲器容量        private String localCharset = "UTF-8"; // 编码格式        public Handler() {        }        public Handler(int bufferSize) {            this(bufferSize, null);        }        public Handler(String localCharset) {            this(-1, localCharset);        }        public Handler(int bufferSize, String localCharset) {            if (bufferSize > 0) {                this.bufferSize = bufferSize;            }            if (localCharset != null) {                this.localCharset = localCharset;            }        }        /*         * 连接请求处理方法         */        public void handleAccept(SelectionKey selectionKey) throws IOException {            // 通过选择器键获取服务器套接字通道,通过accept()方法获取套接字通道连接            SocketChannel socketChannel = ((ServerSocketChannel) selectionKey.channel()).accept();            // 设置套接字通道为非阻塞模式            socketChannel.configureBlocking(false);            // 为套接字通道注册选择器,该选择器为服务器套接字通道的选择器,即选择到该SocketChannel的选择器            // 设置选择器关心请求为读操作,设置数据读取的缓冲器容量为处理器初始化时候的缓冲器容量            socketChannel.register(selectionKey.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(bufferSize));        }        public void handleRead(SelectionKey selectionKey) throws IOException {            // 获取套接字通道            SocketChannel socketChannel = (SocketChannel) selectionKey.channel();            // 获取缓冲器并进行重置,selectionKey.attachment()为获取选择器键的附加对象            ByteBuffer byteBuffer = (ByteBuffer) selectionKey.attachment();            byteBuffer.clear();            // 没有内容则关闭通道            if (socketChannel.read(byteBuffer) == -1) {                socketChannel.close();            } else {                // 将缓冲器转换为读状态                byteBuffer.flip();                // 将缓冲器中接收到的值按localCharset格式编码保存                String receivedRequestData = Charset.forName(localCharset).newDecoder().decode(byteBuffer).toString();                System.out.println("接收到客户端的请求数据:" + receivedRequestData);                // 返回响应数据给客户端                String responseData = "已接收到你的请求数据,响应数据为:(响应数据)";                byteBuffer = ByteBuffer.wrap(responseData.getBytes(localCharset));                socketChannel.write(byteBuffer);                // 关闭通道                socketChannel.close();            }        }    }    public static void main(String[] args) {        try {            // 创建ServerSocketChannel通道,绑定监听端口为8080            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();            serverSocketChannel.socket().bind(new InetSocketAddress(8080));            // 设置为非阻塞模式            serverSocketChannel.configureBlocking(false);            // 注册选择器,设置选择器选择的操作类型            Selector selector = Selector.open();            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);            // 创建处理器            Handler handler = new Handler(1204);            while (true) {                // 等待请求,每次等待阻塞3s,超过时间则向下执行,若传入0或不传值,则在接收到请求前一直阻塞                if (selector.select(3000) == 0) {                    System.out.println("等待请求超时......");                    continue;                }                System.out.println("-----处理请求-----");                // 获取待处理的选择键集合                Iterator
keyIterator = selector.selectedKeys().iterator(); while (keyIterator.hasNext()) { SelectionKey selectionKey = keyIterator.next(); try { // 如果是连接请求,调用处理器的连接处理方法 if (selectionKey.isAcceptable()) { handler.handleAccept(selectionKey); } // 如果是读请求,调用对应的读方法 if (selectionKey.isReadable()) { handler.handleRead(selectionKey); } } catch (IOException e) { keyIterator.remove(); continue; } } // 处理完毕从待处理集合移除该选择键 keyIterator.remove(); } } catch (IOException e) { e.printStackTrace(); } }}

Client

package spring.server;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SocketChannel;public class Client {    public static void main(String[] args) throws IOException {        SocketChannel socketChannel = SocketChannel.open();        socketChannel.connect(new InetSocketAddress("127.0.0.1", 8080));        String newData = "New String to write to file..." + System.currentTimeMillis();        ByteBuffer buf = ByteBuffer.allocate(48);        buf.clear();        buf.put(newData.getBytes());        buf.flip();        while (buf.hasRemaining()) {            socketChannel.write(buf);        }//        socketChannel.configureBlocking(false);//        socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));////        while(! socketChannel.finishConnect() ){//            //wait, or do something else...    //        }                socketChannel.close();    }}

 

转载于:https://www.cnblogs.com/chenss15060100790/p/9368959.html

你可能感兴趣的文章
感谢Leslie Ma
查看>>
几种排序方法
查看>>
查看数据库各表的信息
查看>>
第一阶段测试题
查看>>
第二轮冲刺第五天
查看>>
图片压缩
查看>>
Hadoop-2.6.5安装
查看>>
[poj-2985]The k-th Largest Group_Treap+并查集
查看>>
2018年移动用户界面的三种最潮趋势
查看>>
小甲鱼python视频第三讲(课堂笔记)
查看>>
JMeter压力测试及并发量计算-2
查看>>
Eclipse调试Bug的七种常用技巧
查看>>
go 语言如何跨平台编译
查看>>
重构大数据统计
查看>>
Fortran学习笔记2(变量声明)
查看>>
Trie树
查看>>
A/B test
查看>>
Ad Hoc网络概念、特点和比较
查看>>
2018牛客多校第四场 J.Hash Function
查看>>
ZOJ 解题报告索引
查看>>