赞
踩
在进入代码之前,我们先了解一下选择器:Selector,网络编程的大哥大,服务器可以执行一个线程,运行Selector程序,进行监听操作。它的作用是检查一个或者多个通道的状态是否可读。
Selector 中常用的方法:
SelectionKey 表示 SelectionKey 和网络通道直接的关系
int OP_ACCEPT; 16 需要连接
int OP_CONNECT; 8 已经连接
Int OP_WRITE; 4 写入操作
int OP_READ; 1 读取操作
方法:
服务端Socket程序对应的Channel通道
方法 | 作用 |
---|---|
public static ServerSocketChannel open() | 开启服务器ServerSocketChannel通道 |
public final ServerSocketChannel bind(SocketAddress local); | 设置服务器端端口号 |
public final SelectableChannel configureBlocking(boolean block); | 设置阻塞或非阻塞模式,false 表示非阻塞 |
public SocketChannel accept() | 获取一个客户端连接,并且得到对应的操作通道 |
public final SelectionKey register(Selector sel, int ops) | 注册当前选择器,并且选择监听什么事件 |
客户端Socket对应的Channel对象
方法 | 作用 |
---|---|
static SocketChannel open() | 打开一个Socket客户端Channel对象 |
final SelectableChannel configureBlocking(boolean block) | 设置是阻塞状态,还是非阻塞状态 |
boolean connect(SocketAddress remote) | 连接服务器 |
boolean finishConnect() | 如果connect连接失败,可以通过finishConnect继续连接 |
final SelectionKey register(Selector sel, int ops, Object attechment); | 注册当前SocketChannel,选择对应的监听操作,并且可以带有Object attachment参数 |
final void close() | 关闭SocketChannel |
public static void main(String[] args) throws IOException { // 1. 开启服务器 ServerSocketChannel serverSocket = ServerSocketChannel.open(); // 2. 开启Selector Selector selector = Selector.open(); // 3. 服务端代码绑定端口号 serverSocket.bind(new InetSocketAddress(8848)); // 4. 设置非阻塞状态 serverSocket.configureBlocking(false); //5. ServerSocketChannel 注册--> Selector 返回值是一个SelectionKey serverSocket.register(selector, SelectionKey.OP_ACCEPT); while (true) { if (0 == selector.select(1000)) { // 0 == selector.select(1000) 表示没有连接到客户端 continue; } Iterator<SelectionKey> selectionKeys = selector.selectedKeys().iterator(); while (selectionKeys.hasNext()) { SelectionKey selectionKey = selectionKeys.next(); //连接请求 if (selectionKey.isAcceptable()) { System.out.println("客户端请求连接!!!"); SocketChannel socket = serverSocket.accept(); socket.configureBlocking(false); socket.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024 * 4)); } //可读 if (selectionKey.isReadable()) { SocketChannel socket = (SocketChannel) selectionKey.channel(); ByteBuffer buffer = (ByteBuffer) selectionKey.attachment(); socket.read(buffer); System.out.println("客户端发送数据:" + new String(buffer.array())); } selectionKeys.remove(); } } }
//main方法内 SocketChannel socket = SocketChannel.open(); socket.configureBlocking(false); InetSocketAddress address = new InetSocketAddress("192.168.1.110", 8848); //l连接服务器 if (!socket.connect(address)) { while (!socket.finishConnect()) { System.out.println("保持呼叫服务器状态,但是我还能做点别的事情~~~ 等待2s继续申请连接~~~"); Thread.sleep(2000); } } //准备一个数据存入到缓冲区 ByteBuffer buffer = ByteBuffer.wrap("你好,服务器,我在等你...".getBytes()); socket.write(buffer); new Scanner(System.in).nextLine();
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。