JAVA NIO 服务器端简单实现例子

Java NIO 服务器端简单实现例子分享:
注意:

  1.NIO主要用于服务端,若用来客户端相对于排污泵它带来的额外复杂性有点不值得。

  2.用于编码解码字符集请根据您的机器缺省字符集进行调整,如GB2312,GBK,UTF-8,UTF-16等,若出现乱码请更换之。

  3.BufferSize请根据您可能发送接收的最大字符串长度进行相应调整。

  代码:

package com.heyang.biz.server.test.nio;

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;


/**
 * NIO 服务器
 * 说明:
 * 作者:何杨(heyang78@gmail.com)
 * 创建时间:2011-1-3 下午12:09:02
 * 修改时间:2011-1-3 下午12:09:02
 */
public class NIOServer{
    // 本地字符集
    private static final String LocalCharsetName = "gb2312";

    // 本地服务器监听的端口
    private static final int Listenning_Port=8888;

    // 缓冲区大小
    private static final int Buffer_Size=1024;

    // 超时时间,单位毫秒
    private static final int TimeOut=3000;

    public static void main(String[] args) throws Exception{
        // 创建一个在本地端口进行监听的服务Socket信道.并设置为排污泵塞方式
        ServerSocketChannel serverChannel=ServerSocketChannel.open();
        serverChannel.socket().bind(new InetSocketAddress(Listenning_Port));
        serverChannel.configureBlocking(false);

        // 创建一个选择器并将serverChannel注册到它上面
        Selector selector=Selector.open();
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);

        while(true){
            // 等待某个信道就绪
            if(selector.select(TimeOut)==0){
                System.out.println(".");
                continue;
            }

            // 获得就绪信道的键迭代器
            Iterator<SelectionKey> keyIter=selector.selectedKeys().iterator();

            // 使用迭代器进行遍历就绪信道
            while(keyIter.hasNext()){
                SelectionKey key=keyIter.next();

                // 这种情况是有客户端连接过来,准备一个clientChannel与之通信
                if(key.isAcceptable()){
                    SocketChannel clientChannel=((ServerSocketChannel)key.channel()).accept();
                    clientChannel.configureBlocking(false);
                    clientChannel.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocate(Buffer_Size));
                }

                // 客户端有写入时
                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();

                      // 将获得字节字符串(使用Charset进行解码)
                      String receivedString=Charset.forName(LocalCharsetName).newDecoder().decode(buffer).toString();

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

                      // 准备发送的文本
                      String sendString="你好,客户端. 已经收到你的信息"+receivedString;

                      // 将要发送的字符串编码(使用Charset进行编码)后再对上海减压阀进行包装
                      buffer=ByteBuffer.wrap(sendString.getBytes(LocalCharsetName));

                      // 发送回去
                      clientChannel.write(buffer);

                      // 设置为下一次读取或是写入做准备
                      key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                    }
                }

                keyIter.remove();
            }
        }

    }
}

  与之配合的客户端代码,没有采用NIO方式。

package com.heyang.biz.server.test.nio;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

 

public class TestClient{
    public static void main(String[] args) throws Exception{
        Socket s=new Socket("127.0.0.1",8888);

        InputStream  inStram=s.getInputStream();
        OutputStream outStream=s.getOutputStream();

        // 输出
        PrintWriter out=new PrintWriter(outStream,true);

        out.print("getPublicKey你好!");
        out.flush();

        s.shutdownOutput();// 输出内蒙结束

        // 输入
        Scanner in=new Scanner(inStram);
        StringBuilder sb=new StringBuilder();
        while(in.hasNextLine()){
            String line=in.nextLine();
            sb.append(line);
        }
        String response=sb.toString();
        System.out.println("response="+response);
    }
}

  服务器端的输出:

  接收到信息:getPublicKey你好!

  客户端的输出:

  response=你好,客户端。 已经收到你的信息getPublicKey你好!




Java网络编程(一) 是通过 ServerSocket 和 Socket 建立TCP连接传输数据的。在NIO中,对应的连接方式则为 ServerSocketChannel 和 SocketChannel,这样在建立连接的同时也创建了Channel,接下来就可以如 Java NIO (一) 中使用 Buffer 来传输数据。

下面是NIO形式的Server端代码

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class ServerSocketChannelTest {

public static void main(String[] args) throws IOException, InterruptedException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 创建ServerSocketChannel
InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), 10000);
serverSocketChannel.socket().bind(address);

SocketChannel socketChannel = serverSocketChannel.accept(); // 和ServerSocket类似的accept监听
System.out.println("Connected: " + address);

ByteBuffer buffer = ByteBuffer.allocate(1024); // 创建Buffer
while (true) {
try {
buffer.clear();
if (socketChannel.read(buffer) > 0) { // 接收数据,也是以阻塞方式
buffer.flip(); // 设置成读取状态
byte[] dst = new byte[buffer.limit()];
buffer.get(dst); // 将byte数组取出
System.out.println(new String(dst));
}
Thread.sleep(100);
} catch (Exception e) {
System.out.println("Connection Close");
break;
}
}
}

}


对应NIO形式的Client代码

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ClientSocketChannelTest {

public static void main(String[] args) throws IOException, InterruptedException {
SocketChannel socketChannel = SocketChannel.open(); // 创建SocketChannel
InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), 10000);
socketChannel.socket().connect(address);

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

ByteBuffer buffer = ByteBuffer.allocate(1024); // 创建Buffer
while (true) {
try {
buffer.clear();
String time = sdf.format(new Date());
buffer.put(time.getBytes());
buffer.flip(); // 设置成读取状态
socketChannel.write(buffer); // 发送数据
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("Connection Close");
break;
}
}
}

}


运行结果如下

Connected: ali-52775n/10.13.180.80:10000
2013-01-05 19:11:42
2013-01-05 19:11:43
2013-01-05 19:11:44
2013-01-05 19:11:45
2013-01-05 19:11:46


//Java NIO (异步IO)Socket通信例子:

  服务器代码:

  import java.net.*;

  import java.nio.*;

  import java.nio.channels.*;

  import java.util.*;

  public class server

  {

  ServerSocketChannel ssc ;

  public void start()

  {

  try

  {

  Selector selector = Selector.open();

  ServerSocketChannel ssc=ServerSocketChannel.open();

  ssc.configureBlocking(false);

  ServerSocket ss=ssc.socket();

  InetSocketAddress address = new InetSocketAddress(55555);

  ss.bind(address);

  ssc.register(selector, SelectionKey.OP_ACCEPT);

  System.out.println("端口注册完毕!");

  while(true)

  {

  selector.select();

  Set<SelectionKey> selectionKeys=selector.selectedKeys();

  Iterator<SelectionKey> iter=selectionKeys.iterator();

  ByteBuffer echoBuffer=ByteBuffer.allocate(20);

  SocketChannel sc;

  while(iter.hasNext())

  {

  SelectionKey key=iter.next();

  if((key.readyOps()&SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT)

  {

  ServerSocketChannel subssc=(ServerSocketChannel)key.channel();

  sc=subssc.accept();

  sc.configureBlocking(false);

  sc.register(selector, SelectionKey.OP_READ);

  iter.remove();

  System.out.println("有新连接:"+sc);

  }

  else if((key.readyOps()&SelectionKey.OP_READ)==SelectionKey.OP_READ)

  {

  sc=(SocketChannel) key.channel();

  while(true)

  {

  echoBuffer.clear();

  int a;

  try

  {

  a=sc.read(echoBuffer);

  }

  catch(Exception e)

  {

  e.printStackTrace();

  break;

  }

  if(a==-1) break;

  if(a>0)

  {

  byte[] b=echoBuffer.array();

  System.out.println("接收数据: "+new String(b));

  echoBuffer.flip();

  sc.write(echoBuffer);

  System.out.println("返回数据: "+new String(b));

  }

  }

  sc.close();

  System.out.println("连接结束");

  System.out.println("=============================");

  iter.remove();

  }

  }

  }

  }

  catch (Exception e)

  {

  e.printStackTrace();

  }

  }

  }

  客户端代码:

  import java.net.*;

  import java.nio.*;

  import java.nio.channels.*;

  public class client

  {

  public void start()

  {

  try

  {

  SocketAddress address = new InetSocketAddress("localhost",55555);

  SocketChannel client=SocketChannel.open(address);

  client.configureBlocking(false);

  String a="asdasdasdasddffasfas";

  ByteBuffer buffer=ByteBuffer.allocate(20);

  buffer.put(a.getBytes());

  buffer.clear();

  int d=client.write(buffer);

  System.out.println("发送数据: "+new String(buffer.array()));

  while(true)

  {

  buffer.flip();

  int i=client.read(buffer);

  if(i>0)

  {

  byte[] b=buffer.array();

  System.out.println("接收数据: "+new String(b));

  client.close();

  System.out.println("连接关闭!");

  break;

  }

  }

  }

  catch(Exception e)

  {

  e.printStackTrace();

  }

  }

  }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值