📄 socketchanneldemo.java
字号:
// ==================== Program Discription =====================// 程序名称:示例12-14 : SocketChannelDemo.java// 程序目的:学习java nio#SocketChannel// ==============================================================import java.nio.ByteBuffer;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.nio.channels.Selector;import java.nio.channels.SelectionKey;import java.nio.channels.SelectableChannel;import java.net.Socket;import java.net.ServerSocket;import java.net.InetSocketAddress;import java.util.Iterator;public class SocketChannelDemo{ public static int PORT_NUMBER = 23;//监听端口 ServerSocketChannel serverChannel; ServerSocket serverSocket ; Selector selector ; //Allocates a new direct byte buffer. private ByteBuffer buffer = ByteBuffer.allocateDirect (1024); public static void main (String [] args) throws Exception { SocketChannelDemo server=new SocketChannelDemo(); server.init(args); server.startWork(); } public void init (String [] argv)throws Exception { int port = PORT_NUMBER; if (argv.length > 0) { port = Integer.parseInt (argv [0]); } System.out.println ("Listening on port " + port); // 分配一个ServerSocketChannel serverChannel = ServerSocketChannel.open(); // 从ServerSocketChannel里获得一个对应的Socket serverSocket = serverChannel.socket(); // 生成一个Selector selector = Selector.open(); // 把Socket绑定到端口上 serverSocket.bind (new InetSocketAddress (port)); //serverChannel为非bolck serverChannel.configureBlocking (false); // 通过Selector注册ServerSocetChannel serverChannel.register (selector, SelectionKey.OP_ACCEPT); } public void startWork()throws Exception { while (true) { int n = selector.select();//获得io准备就绪的channel数量 if (n == 0) { continue; // 没有channel准备就绪,继续执行 } // 用一个iterator返回selector的selectedkeys Iterator it = selector.selectedKeys().iterator(); // 处理每一个SelectionKey while (it.hasNext()) { SelectionKey key = (SelectionKey) it.next(); // 判断是否有新的连接到达 if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel();//返回SelectionKey的ServerSocketChannel。 SocketChannel channel = server.accept(); registerChannel (selector, channel, SelectionKey.OP_READ); doWork (channel); } // 判断是否有数据在此channel里需要读取 if (key.isReadable()) { processData (key); } // remove selectedkeys it.remove(); } } } protected void registerChannel (Selector selector, SelectableChannel channel, int ops) throws Exception { if (channel == null) { return; // could happen } // set the new channel non-blocking channel.configureBlocking (false); // register it with the selector channel.register (selector, ops); } //处理接收的数据 protected void processData (SelectionKey key) throws Exception { SocketChannel socketChannel = (SocketChannel) key.channel(); int count; buffer.clear(); // 清空buffer // 读取所有的数据 while ((count = socketChannel.read (buffer)) > 0) { buffer.flip(); // make buffer readable // send the data, don't assume it goes all at once while (buffer.hasRemaining()) { //如果收到回车键,则在返回的字符前增加[echo]$字样 if(buffer.get()==(char)13) { buffer.clear(); buffer.put("[echo]$".getBytes()); buffer.flip(); } socketChannel.write (buffer);//在socket里些数据 } buffer.clear(); // 清空buffer } if (count < 0) { // count<0,说明已经读取完毕 socketChannel.close(); } } private void doWork (SocketChannel channel)throws Exception { buffer.clear(); buffer.put ("Hello,I am working,please input some thing,and i will echo to you!\r\n[echo]$".getBytes()); buffer.flip(); //Writes a sequence of bytes to this channel from the given buffer. channel.write (buffer); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -