博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javaIO
阅读量:4068 次
发布时间:2019-05-25

本文共 8021 字,大约阅读时间需要 26 分钟。

文章目录

一、java网络编程

1、基础知识

a、ip地址和端口号
b、TCP和UDP协议
c、URL
public static void main(String[] args) throws IOException {        //使用URL读取网页内容        //1、创建一个URL实例        URL url = new URL("http://www.baidu.com");        InputStream inputStream = url.openStream();// 2、使用openStream()获取资源的字节输入流        //3、将字节流转换为字符流,如果不指定编码,中文可能会出现乱码        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");        //4、为字符输入流添加缓存,提高读取效率        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);        String string = bufferedReader.readLine();  //5、读取数据        while(string != null) {            System.out.println(string);  //输出数据            string = bufferedReader.readLine();        }        bufferedReader.close();        inputStreamReader.close();        inputStream.close();    }
d、InetAddress

2、socket

a、创建socket实例
b、客户端连接
步骤:

1)、创建socket对象

2)、建立连接后,通过输出流向服务端发送请求信息
3)、通过输入流获取服务端返回的响应信息
4)、关闭响应资源

public static void main(String[] args) throws IOException {        //客户端        //1、创建socket对象        Socket socket = new Socket("localhost", 10086);        //2、获取输出流,向服务器发送信息        OutputStream outputStream = socket.getOutputStream();        PrintWriter printWriter = new PrintWriter(outputStream);//将输出流包装成打印流        printWriter.write("用户名: admin; 密码:123");        printWriter.flush();        socket.shutdownOutput();        //3、获取输入流,并读取服务端的响应信息        InputStream inputStream = socket.getInputStream();        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));        String string = null;        while((string = bufferedReader.readLine()) != null){            System.out.println("我是客户端,服务端说:" + string);        }        //4、关闭响应资源        bufferedReader.close();        inputStream.close();        printWriter.close();        outputStream.close();        socket.close();    }
c、服务端连接
步骤:

1)、创建ServerSocket对象, 绑定监听端口

2)、通过accept() 方法监听客户端请求
3)、连接建立后,通过输入流读取客户端发送的请求信息
4)、通过输出流向客户端发送信息
5)、关闭相关资源

public static void main(String[] args) throws IOException {        /**         *服务端,基于Tcp协议的socket通信,实现用户登录         */        //1、创建serverSocket,指定绑定的端口,并监听此端口        ServerSocket serverSocket = new ServerSocket(10086);        //2、调用accept()方法开始监听,等待客户端的连接        Socket socket = serverSocket.accept();        //3、获取输入流,并读取客户端信息        InputStream inputStream = socket.getInputStream();        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);        String string = null;        while((string = bufferedReader.readLine()) != null){            System.out.println("我是服务端,客户端说:"+ string);        }        socket.shutdownInput();  //关闭输入流        //4、获取输出流,向客户端发送信息        OutputStream outputStream = socket.getOutputStream();        PrintWriter printWriter = new PrintWriter(outputStream);        printWriter.write("欢迎您!");        printWriter.flush();        //5、关闭资源        printWriter.close();        outputStream.close();        bufferedReader.close();        inputStreamReader.close();        inputStream.close();        socket.close();        serverSocket.close();    }
d、总结

1)、创建ServerSocket和Socket

2) 、打开连接到Socket的输入输出流
3)、按照协议对Socket进行读写操作
4)、关闭输入输出流、关闭socket

二、阻塞IO

1、java的IO接口

数据和传输方式是最影响效率的两个方面。

a、基于字节操作的IO接口

b、基于字符操作的IO接口

c、基于磁盘操作的IO接口

d、基于网络操作的IO接口

2、阻塞IO的通信模型

在这里插入图片描述

3、总结

a 、 BIO数据在写入OutputStream和从InputStream读取时,都有可能发生阻塞

b 、当前一些需要大量http长连接的情况

c 、需要另外一种新的IO操作方式

三、NIO

1、工作原理

(补充)

在这里插入图片描述

2、通信模型

(补充)

在这里插入图片描述

3、实例

客户端代码:
public class NIOClient {    //通道管理器    private Selector selector;    /**     *获取一个socket通道,并对该通道做一些初始化工作     */    public void initClient(String ip, int port) throws IOException {        //获取一个socket通道        SocketChannel socketChannel = SocketChannel.open();        socketChannel.configureBlocking(false);  //设置通道为非阻塞        //获取一个通道管理器        this.selector = Selector.open();        //客户端连接服务器,其实方法执行并没有实现连接,        // 需要在Listen()方法中调用channel.finishConnect()才能完成连接        socketChannel.connect(new InetSocketAddress(ip, port));        //将通道管理器和该通道绑定,并为该通道注册SelectionKey.OP_CONNECT        socketChannel.register(selector, SelectionKey.OP_CONNECT);    }    /**     *采用轮寻的方式监听selector上是否有需要处理的事件,如果有,则进行处理     */    public void listen() throws IOException{        //轮寻访问selector        while (true){            selector.select();            //获取selector中选中的项的迭代器            Iterator iterator = this.selector.selectedKeys().iterator();            while(iterator.hasNext()){                SelectionKey selectionKey = (SelectionKey)iterator.next();                //删除已选的key,以防重复处理                iterator.remove();                //连接事件发生                if(selectionKey.isAcceptable()){                    SocketChannel socketChannel = (SocketChannel)selectionKey.channel();                    //如果正在连接,则完成连接                    if(socketChannel.isConnectionPending()){                        socketChannel.finishConnect();                    }                    //设置成非阻塞                    socketChannel.configureBlocking(false);                    //在这里可以给服务器发送消息                    socketChannel.write(ByteBuffer.wrap(new String("向服务端发送了一条消息").getBytes()));                    //在和服务端连接成功后,为了可以接收到服务端的消息,需要给通道设置读的权限                    socketChannel.register(this.selector, SelectionKey.OP_READ);                }else if(selectionKey.isReadable()){//获取了可读的条件                    read(selectionKey);                }            }        }    }    /**     * 处理读取服务端发送来的信息的事件     */    public void read(SelectionKey selectionKey){        //和服务端的read方法一样    }}
服务端代码
public class NIOServer {    //通道管理器    private Selector selector;    /**     *获取一个ServerSocket通道,并对该通道做一些初始化工作     */    public void initServer(int port) throws IOException {        //获取一个ServerSocket通道        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();        //设置通道为非阻塞        serverSocketChannel.configureBlocking(false);        //将该通道对应的ServerSocket绑定到端口        serverSocketChannel.socket().bind(new InetSocketAddress(port));        //获得一个通道管理器        selector = Selector.open();        //将通道管理器和该通道进行绑定,并为该通道注册SelectionKey.OP_ACCEPT事件,注册该事件后,        // 当事件到达时,selector.select()会返回,如果该事件没到达,selector.select()会一直阻塞        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);    }    /**     *采用轮寻的方式监听selector上是否有需要处理的事件,如果有,则进行处理     */    public void listen() throws IOException{       System.out.println("服务器启动成功");       //轮寻访问selector        while(true){            //当注册的事件到达时,方法返回,否则,该方法一直阻塞            selector.select();            //获取selector中选中的项的迭代器,选中的项为注册的事件            Iterator iterator = this.selector.selectedKeys().iterator();            if(iterator.hasNext()){                SelectionKey selectionKey = (SelectionKey) iterator.next();                //删除已选的key,以防重复处理                iterator.remove();                //客户端请求连接事件                if(selectionKey.isAcceptable()){                    ServerSocketChannel serverSocketChannel = (ServerSocketChannel)selectionKey.channel();                    //获得和客户端连接的通道                    SocketChannel socketChannel = serverSocketChannel.accept();                    //设置成非阻塞                    socketChannel.configureBlocking(false);                    //在这里可以给客户端发送消息                    socketChannel.write(ByteBuffer.wrap(new String("向客户端发送一条消息").getBytes()));                    //在和客户端连接成功后,为了可以接收到客户端的信息,需要给通道设置读的权限                    socketChannel.register(this.selector, SelectionKey.OP_READ);                }else if(selectionKey.isReadable()) {  //获得了可以读的权限                    read(selectionKey );                }            }        }    }    /**     * 处理读取客户端发送来的信息的事件     */    public void read(SelectionKey selectionKey) throws IOException{        //服务端可以读取消息: 得到事件发生的socket通道        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();        //创建读取的缓存区        ByteBuffer byteBuffer = ByteBuffer.allocate(10);        socketChannel.read(byteBuffer);        byte[] data = byteBuffer.array();        String msg = new String(data).trim();    }}

转载地址:http://shaji.baihongyu.com/

你可能感兴趣的文章
php开发微服务注册到eureka中(使用sidecar)
查看>>
mybatis mybatis plus mybatis jpa hibernate spring data jpa比较
查看>>
支付宝生活号服务号 用户信息获取 oauth2 登录对接 springboot java
查看>>
CodeForces #196(Div. 2) 337D Book of Evil (树形dp)
查看>>
uva 12260 - Free Goodies (dp,贪心 | 好题)
查看>>
uva-1427 Parade (单调队列优化dp)
查看>>
【设计模式】学习笔记13:组合模式(Composite)
查看>>
hdu 1011 Starship Troopers (树形背包dp)
查看>>
hdu 1561 The more, The Better (树形背包dp)
查看>>
【设计模式】学习笔记14:状态模式(State)
查看>>
poj 1976 A Mini Locomotive (dp 二维01背包)
查看>>
斯坦福大学机器学习——因子分析(Factor analysis)
查看>>
项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved
查看>>
linux对于没有写权限的文件如何保存退出vim
查看>>
Windows下安装ElasticSearch6.3.1以及ElasticSearch6.3.1的Head插件
查看>>
IntelliJ IDEA 下的svn配置及使用的非常详细的图文总结
查看>>
【IntelliJ IDEA】idea导入项目只显示项目中的文件,不显示项目结构
查看>>
ssh 如何方便的切换到其他节点??
查看>>
JSP中文乱码总结
查看>>
Java-IO-File类
查看>>