用java.nio.*进行网络编程
作者:网管整理 来源:bitsCN.com PV:
1000
前言
因为打算用java编写异步通信的server和client程序,笔者便学习使用java.nio 开发包,其间遇到一些问题,上网却发现网上对它的应用描述的不是很多。所以,笔者不惜班门弄斧,做些简单的讨论,以便大家更进一步的讨论。
对相关类的简单介绍 SocketChannel类是抽象类,通过调用它的静态函数open(),可生成一个 ServerSocketChannel也是通过调用它的静态函数open()生成的,只是它不能
罗嗦了半天,还是看看最简单的C/S实现吧,服务器提供了基本的回射(echo)功
源码分析 中国网管论坛
1.服务器端: class AsyncServer implements Runnable{ while(true){ int n = s.select(); if (n == 0) {//没有指定的I/O事件发生 continue; } Iterator it = s.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey) it.next(); if (key.isAcceptable()) {//侦听端信号触发 ServerSocketChannel server = (ServerSocketChannel) key.channel(); //接受一个新的连接 SocketChannel sc = server.accept(); sc.configureBlocking(false); //设置该socket的异步信号OP_READ:当socket可读时, BBS.bitsCN.com网管论坛
//触发函数DealwithData();
sc.register(s,SelectionKey.OP_READ); } if (key.isReadable()) {//某socket可读信号 DealwithData(key); } it.remove(); } } } catch(Exception e){ e.printStackTrace(); } } public void DealwithData(SelectionKey key) throws IOException{ int count; //由key获取指定socketchannel的引用 SocketChannel sc = (SocketChannel)key.channel(); r_buff.clear(); //读取数据到r_buff while((count = sc.read(r_buff))> 0) ; bitsCN.Com //确保r_buff可读 r_buff.flip(); w_buff.clear(); //将r_buff内容拷入w_buff w_buff.put(r_buff); w_buff.flip(); //将数据返回给客户端 EchoToClient(sc); w_buff.clear(); r_buff.clear(); } public void EchoToClient(SocketChannel sc) throws IOException{ while(w_buff.hasRemaining()) sc.write(w_buff); } public static void main(String args[]){ if(args.length > 0){ port = Integer.parseInt(args[0]); } new AsyncServer(); } } 在当前目录下运行: javac AsynServer.java 后,若无编译出错,接下来可运行: java AsynServer 或 java AsynServer ×××(端口号) 上述服务程序在运行时,可指定其侦听端口,否则程序会取8848为默认端口。 2.客户端的简单示例:
//////////////////////// //AsyncClient.java // by zztudou@163.com //////////////////////// import java.nio.channels.SocketChannel; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.Selector; import java.nio.channels.SelectionKey; 中国网管联盟
import java.io.IOException; class AsyncClient{
private SocketChannel sc; private final int MAX_LENGTH = 1024; private ByteBuffer r_buff = ByteBuffer.allocate(MAX_LENGTH); private ByteBuffer w_buff = ByteBuffer.allocate(MAX_LENGTH); private static String host ; private static int port = 8848; public AsyncClient(){ try { InetSocketAddress addr = new InetSocketAddress(host,port); //生成一个socketchannel sc = SocketChannel.open(); //连接到server sc.connect(addr); while(!sc.finishConnect()) ; System.out.println("connection has been established!..."); while(true){ //回射消息 String echo; try{ System.err.println("Enter msg you'd like to send: "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //输入回射消息 echo = br.readLine(); //把回射消息放入w_buff中 w_buff.clear(); w_buff.put(echo.getBytes()); w_buff.flip(); }catch(IOException ioe){ System.err.println("sth. is wrong with br.readline() "); } //发送消息 while(w_buff.hasRemaining()) sc.write(w_buff); w_buff.clear(); //进入接收状态 Rec(); //间隔1秒 Thread.currentThread().sleep(1000); } }catch(IOException ioe){ ioe.printStackTrace(); } catch(InterruptedException ie){ ie.printStackTrace(); } } ////////////
//读取server端发回的数据,并显示 public void Rec() throws IOException{ int count; r_buff.clear(); count=sc.read(r_buff); r_buff.flip(); byte[] temp = new byte[r_buff.limit()]; r_buff.get(temp); System.out.println("reply is " + count +" long, and content is: " + new String(temp)); } public static void main(String args[]){ if(args.length < 1){//输入需有主机名或IP地址 try{ System.err.println("Enter host name: "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); host = br.readLine(); }catch(IOException ioe){ System.err.println("sth. is wrong with br.readline() "); } } else if(args.length == 1){ host = args[0]; } else if(args.length > 1){ host = args[0]; port = Integer.parseInt(args[1]); }
new AsyncClient(); 在当前目录下运行: 总结 在当前目录下运行: 2.客户端的简单示例:
//////////////////////// //AsyncClient.java // by zztudou@163.com //////////////////////// import java.nio.channels.SocketChannel; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.Selector; import java.nio.channels.SelectionKey; DL.bitsCN.com网管软件下载 import java.io.IOException; class AsyncClient{ if(args.length < 1){//输入需有主机名或IP地址 try{ System.err.println("Enter host name: "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); host = br.readLine(); }catch(IOException ioe){ System.err.println("sth. is wrong with br.readline() "); } } else if(args.length == 1){ host = args[0]; } else if(args.length > 1){ host = args[0]; port = Integer.parseInt(args[1]); }
new AsyncClient();
在当前目录下运行: 总结 |
|
来自: 雨忆 > 《java网络编程》