NIO通讯

在网络编程的过中,使用到通道中的socketChannel和serverSocketChannel这两个类,其中socketChannel类可以读写TCP Socket ,数据必须编码到ByteBuffer对象中来完成读写。
1 创建socketChannel对象
方法一
SocketAddress address=new InetSocketAddress("wwww.baidu.com",1233);
SocketChannel channel=SocketChannel.open(address);
方法二
SocketAddress address=new InetSocketAddress("wwww.baidu.com",1233);
SocketChannel channel=SocketChannel.open();
channel.configureBlocking(false); //无阻塞方式打开通道
channel.connect(address);
2 读取
使用方法read(ByteBuffer dst)读取对象中的数据
注意:
如果是通道是阻塞的该方法在流末尾会返回一个-1 ,如果通道是非阻塞的该方法会返回0
3 写入
write(ByteBuffer src) 
4 关闭
close() 使用isope()检查是否关闭
 serverSocketChannel
 serverSocketChannel只有一个目的:接受入站连接,无法读取,写入或者连接serverSocketChannel,他支持的唯一操作是接受一个新的入站连接
 创建一个socket通道
  ServerSocketChannel serverChannel=ServerSocketChannel.open();     
  SocketAddress address=new InetSocketAddress(80);
  serverChannel.bind(address);
接受连接
SocketChannel channle=serverChannel.accept();
连接分为阻塞连接和非阻塞连接,在阻塞的模式下,accept()方法等待入站连接,在接连建立之前,线程无法进行任何操作,这种策略适用于立即响应每一个请求的简单服务器,阻塞模式是默认模式。
在非阻塞模式情况下,在没有建立连接之前,accept()返回的一个null,非阻塞模式更适合于需要为每一个连接完成大量工作的服务器,这样可以进行并行的处理多个请求,使用configureBlocking(false)设置。

代码如下
服务器端

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
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.util.Iterator;
import java.util.Set;

public class ServerSocketChannelTest {
    public static void main(String[] args) throws IOException {
        ServerSocketChannelTest server=new ServerSocketChannelTest();        
        server.readMessage();
        
    }
    public void readMessage(){
        System.out.println("进入服务端");
        try {
            //使用静态工厂的模式获取ServerSocketChannel
            ServerSocketChannel serverChannel=ServerSocketChannel.open();    
            Selector selector=Selector.open();
            // 绑定接口
            serverChannel.bind(new InetSocketAddress(1233));
            while(true){
            //指定服务器中是否阻塞
            serverChannel.configureBlocking(false);            
            serverChannel.register(selector, SelectionKey.OP_ACCEPT);
            selector.select(20000);
            
            Set<SelectionKey> readKeys=selector.selectedKeys();
            Iterator<SelectionKey> iterable=readKeys.iterator();
            
            while(iterable.hasNext()){
                
                SelectionKey key=iterable.next();                
                if(key.isAcceptable()){
                    handleAccept(key);
                                        
                }else if(key.isWritable()){                    
                    handleWrite(key);
                }else if(key.isReadable()){
                    handleRead(key);
                }
                iterable.remove();
            }
            
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }   
    
    
    public void handleRead(SelectionKey key){        
        SocketChannel sc=(SocketChannel) key.channel();        
        ByteBuffer buf=(ByteBuffer) key.attachment();
        try {                    
            long bytesRead=sc.read(buf);
            while(bytesRead>0){
                buf.flip();
            
                while(buf.hasRemaining()){
                    System.out.print((char)buf.get());
                }
                System.out.println();
                buf.clear();
                bytesRead=sc.read(buf);
            }
            if(bytesRead==-1){
                sc.close();
                }
            
        } catch (IOException e) {
            
            e.printStackTrace();
        }
    }
     
    public void handleAccept(SelectionKey key){
        ServerSocketChannel ssChannel=(ServerSocketChannel) key.channel();
        try {
            SocketChannel channle=ssChannel.accept();
            channle.configureBlocking(false);
            channle.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocateDirect(1000));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void handleWrite(SelectionKey key){
        ByteBuffer buf=(ByteBuffer) key.attachment();
        buf.flip();
        SocketChannel channle=(SocketChannel) key.channel();
        while(buf.hasRemaining()){
            try {
                channle.write(buf);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        buf.compact();
    }

}
客户端

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


public class SocketChannlTest {    
    public static void main(String[] args) {       
        
        for(int i=0;i<10;i++){
        SocketChannel client;
        try {
            client = SocketChannel.open();
            client.configureBlocking(false);
            new Get(client).start();
        } catch (IOException e) {
            e.printStackTrace();
        }    
        
        
        }    
        
        
    }
    
    
    static class Get extends Thread{
        private SocketChannel connection;
        Get(SocketChannel connection){
            this.connection=connection;            
        }
        
        public void run(){
            ByteBuffer buffer=ByteBuffer.allocate(100);
            
            SocketAddress adress=new InetSocketAddress("localhost",1233);
            try {        
            connection.connect(adress);
            if(connection.finishConnect()){
                int i=0;
                while(true){
                    try {
                        TimeUnit.SECONDS.sleep(1);
                        String info="我是+"+i+++"th client";
                        buffer.clear();
                        buffer.put(info.getBytes());
                        buffer.flip();
                        while(buffer.hasRemaining()){
                            System.out.println(buffer.toString());
                            connection.write(buffer);
                        }
                        
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            
            } catch (IOException e) {                
                e.printStackTrace();
            }finally{
                if(connection!=null)
                {
                    try {
                        connection.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }          

            }
            
        }
    }
    
    
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值