精华内容
下载资源
问答
  • 通道(Channel):负责连接 java.nio.channels.Channel 接口: |–SelectableChannel |–SocketChannel |–ServerSocketChannel |–DatagramChannel |–Pipe.SinkChannel |–Pipe.SourceChannel 缓冲区(Buffer)...

    一、使用 NIO 完成网络通信的三个核心:

    1. 通道(Channel):负责连接

      java.nio.channels.Channel 接口:
      |–SelectableChannel
      |–SocketChannel
      |–ServerSocketChannel
      |–DatagramChannel

      |–Pipe.SinkChannel
      |–Pipe.SourceChannel

    2. 缓冲区(Buffer):负责数据的存取

    3. 选择器(Selector):是 SelectableChannel 的多路复用器。用于监控 SelectableChannel 的 IO 状况

    二、实现网络通信

    2.1 SocketChannel

    //客户端
    @Test
    public void client() throws IOException{
    	//1. 获取通道
    	SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
    	
    	//2. 切换非阻塞模式
    	sChannel.configureBlocking(false);
    	
    	//3. 分配指定大小的缓冲区
    	ByteBuffer buf = ByteBuffer.allocate(1024);
    	
    	//4. 发送数据给服务端
    	Scanner scan = new Scanner(System.in);
    	
    	while(scan.hasNext()){
    		String str = scan.next();
    		buf.put((new Date().toString() + "\n" + str).getBytes());
    		buf.flip();
    		sChannel.write(buf);
    		buf.clear();
    	}
    	
    	//5. 关闭通道
    	sChannel.close();
    }
    
    //服务端
    @Test
    public void server() throws IOException{
    	//1. 获取通道
    	ServerSocketChannel ssChannel = ServerSocketChannel.open();
    	
    	//2. 切换非阻塞模式
    	ssChannel.configureBlocking(false);
    	
    	//3. 绑定连接
    	ssChannel.bind(new InetSocketAddress(9898));
    	
    	//4. 获取选择器
    	Selector selector = Selector.open();
    	
    	//5. 将通道注册到选择器上, 并且指定“监听接收事件”
    	ssChannel.register(selector, SelectionKey.OP_ACCEPT);
    	
    	//6. 轮询式的获取选择器上已经“准备就绪”的事件
    	while(selector.select() > 0){
    		
    		//7. 获取当前选择器中所有注册的“选择键(已就绪的监听事件)”
    		Iterator<SelectionKey> it = selector.selectedKeys().iterator();
    		
    		while(it.hasNext()){
    			//8. 获取准备“就绪”的是事件
    			SelectionKey sk = it.next();
    			
    			//9. 判断具体是什么事件准备就绪
    			if(sk.isAcceptable()){
    				//10. 若“接收就绪”,获取客户端连接
    				SocketChannel sChannel = ssChannel.accept();
    				
    				//11. 切换非阻塞模式
    				sChannel.configureBlocking(false);
    				
    				//12. 将该通道注册到选择器上
    				sChannel.register(selector, SelectionKey.OP_READ);
    			}else if(sk.isReadable()){
    				//13. 获取当前选择器上“读就绪”状态的通道
    				SocketChannel sChannel = (SocketChannel) sk.channel();
    				
    				//14. 读取数据
    				ByteBuffer buf = ByteBuffer.allocate(1024);
    				
    				int len = 0;
    				while((len = sChannel.read(buf)) > 0 ){
    					buf.flip();
    					System.out.println(new String(buf.array(), 0, len));
    					buf.clear();
    				}
    			}
    			
    			//15. 取消选择键 SelectionKey
    			it.remove();
    		}
    	}
    }
    

    2.2 DatagramChannel

    @Test
    public void send() throws IOException{
    	DatagramChannel dc = DatagramChannel.open();
    	
    	dc.configureBlocking(false);
    	
    	ByteBuffer buf = ByteBuffer.allocate(1024);
    	
    	Scanner scan = new Scanner(System.in);
    	
    	while(scan.hasNext()){
    		String str = scan.next();
    		buf.put((new Date().toString() + ":\n" + str).getBytes());
    		buf.flip();
    		dc.send(buf, new InetSocketAddress("127.0.0.1", 9898));
    		buf.clear();
    	}
    	
    	dc.close();
    }
    
    	@Test
    	public void receive() throws IOException{
    	DatagramChannel dc = DatagramChannel.open();
    	
    	dc.configureBlocking(false);
    	
    	dc.bind(new InetSocketAddress(9898));
    	
    	Selector selector = Selector.open();
    	
    	dc.register(selector, SelectionKey.OP_READ);
    	
    	while(selector.select() > 0){
    		Iterator<SelectionKey> it = selector.selectedKeys().iterator();
    		
    		while(it.hasNext()){
    			SelectionKey sk = it.next();
    			
    			if(sk.isReadable()){
    				ByteBuffer buf = ByteBuffer.allocate(1024);
    				
    				dc.receive(buf);
    				buf.flip();
    				System.out.println(new String(buf.array(), 0, buf.limit()));
    				buf.clear();
    			}
    		}
    		
    		it.remove();
    	}
    }
    

    2.3 pipe

    //1. 获取管道
    Pipe pipe = Pipe.open();
    	
    //2. 将缓冲区中的数据写入管道
    ByteBuffer buf = ByteBuffer.allocate(1024);
    Pipe.SinkChannel sinkChannel = pipe.sink();
    buf.put("通过单向管道发送数据".getBytes());
    buf.flip();
    sinkChannel.write(buf);
    	
    //3. 读取缓冲区中的数据
    Pipe.SourceChannel sourceChannel = pipe.source();
    buf.flip();
    int len = sourceChannel.read(buf);
    System.out.println(new String(buf.array(), 0, len));
    	
    sourceChannel.close();
    sinkChannel.close();
    
    展开全文
  • vue-socket.io实现长链接

    2020-12-11 17:30:07
    今天介绍vue-socket.io 一个专门问题vuejs提供的plugin,这里实现了一个身份证读卡器的socket长链接。 引入方式一: 只使用了vue-socket.io 的方法,介绍 vue-socket.io其实在socket.io-client基础.

    之前提到ScokJS
    .SockJS是一个浏览器JavaScript库,它提供了一个类似于网络的对象。SockJS提供了一个连贯的、跨浏览器的Javascript API,它在浏览器和web服务器之间创建了一个低延迟、全双工、跨域通信通道。

    今天介绍vue-socket.io 一个专门问题vuejs提供的plugin,这里实现了一个身份证读卡器的socket长链接。

    引入方式一:
    只使用了vue-socket.io 的方法,介绍

    vue-socket.io其实是在socket.io-client基础上做了一层封装,将$socket挂载到vue实例上,同时你可以使用sockets对象轻松实现组件化的事件监听,让你在vue项目中使用起来更方便。

    // main.js 界面中
    npm install vue-socket.io -S
    
    import VueSocketIO from 'vue-socket.io'
    
    Vue.use(
      new VueSocketIO({
        debug: false,
        connection: 'http://127.0.0.1:5000' // xxx填后台给的socket地址,端口号根据实际后台端口写
      })
    )
    
    // 界面中运用 **.vue
    sockets: { // 和created同级
        // 这里是监听事件(也是订阅操作,写法和下面的不同而已)
        connect() {
          // 获取每台客服端生成的id
          console.log('链接服务器')
          console.log('开始读卡')
          this.$socket.emit('startRead')
        },
        // 监听断开连接,函数
        disconnect() {
          console.log('断开服务器连接')
        },
        reconnect() {
          console.log('重新链接')
        }
      },
      mounted() {
      	// 订阅操作
        this.sockets.subscribe('card message', msg => {
          // 解密后是json字符串
          var result1 = Base64.decode(msg)
          const data = JSON.parse(result1)
          // console.log(data) 返回数据信息
          const object = {
            name: data.name,
            sex: data.sex,
            nation: data.nation,
            born: data.born,
            address: data.address,
            cardno: data.cardno,
            police: data.police,
            img: 'data:image/png;base64,' + data.photobase64
          }
          // console.log(object)
          this.$emit('UserInfo', object)
        })
      },
      methods: {
        btnStartRead() {
          console.log('开始读卡')
          this.$socket.emit('startRead')
        },
    
        btnIsRead() {
          this.$socket.emit('isReading', '', function (data) {
            console.log('检查是否正常读卡: ' + data)
          })
        },
        btnStopRead() {
          console.log('停止读卡')
          this.$socket.emit('stopRead')
        },
        btnSetReadOnceTrue() {
          console.log('设置同一张卡只读第一次')
          this.$socket.emit('readOnce', 'true')
        },
        btnSetReadOnceFalse() {
          console.log('设置同一张可重复读取')
          this.$socket.emit('readOnce', 'false')
        },
        btnReadFp() {
          console.log('设置读指纹')
          this.$socket.emit('readFp', 'true')
        },
        btnDontReadFp() {
          console.log('设置不读指纹')
          this.$socket.emit('readFp', 'false')
        }
      }
    

    引入方式二: (使用了vue-socket.io 和 socket.io-client 的方法)
    这种方式目前没有机会功能实现
    区别在SocketIO 这里封装了请求数据,延迟时间等参数!

    // main.js 界面中
    npm install vue-socket.io socket.io-client -S
    
    import SocketIO from 'socket.io-client'
    import VueSocketIO from 'vue-socket.io'
    
    Vue.use(
          new VueSocketIO({
            debug: false,
            connection: SocketIO('http://127.0.0.1:5000', {
              // path: '',
              autoConnect: true,
              transports: ['websocket', 'xhr-polling', 'jsonp-polling'],
              reconnect: true,
              path: '/socket.io/',
              timeout: 300000,
              reconnectionDelayMax: 1000,
              reconnectionDelay: 500
            }) // xxx填后台给的socket地址,端口号根据实际后台端口写
          })
        )
    
    展开全文
  • 通道有一个重要的功能,被称为Scatter/Gather(即矢量IO),它指在多个缓冲区上实现一个简单的I/O操作。用通俗的话来说,就是在write的时候,可以将多个缓冲区中的数据写入一个更大的缓冲区中,然后沿着通道发送;在...

    通道有一个重要的功能,被称为Scatter/Gather(即矢量IO),它是指在多个缓冲区上实现一个简单的I/O操作。用通俗的话来说,就是在write的时候,可以将多个缓冲区中的数据写入一个更大的缓冲区中,然后沿着通道发送;在read的时候,将数据写入多个缓冲区中,将每个缓冲区填满,直到缓冲区的最大空间被消耗完。

    当请求一个Scatter/Gather操作时,请请求会被翻译为适当的本地调用来直接填充或抽取缓冲区,这将减少或避免了缓冲区拷贝和系统调用。Scatter/Gather应该使用直接的ByteBuffer以从本地I/O获取最大性能。

        Scatter操作:

         ByteBuffer header = ByteBuffer.allocateDirect(10);

        ByteBuffer body = ByteBuffer.allocateDirect(80);

          ByteBuffer[] buffers = {header, body};

          int bytesRead = channel.read(buffers);

        Gather操作:

         body.clear();

         body.put("Foo".getBytes()).flip();

          header.clear();

           header.putShort(1).putLong(body.limit()).flip();

           long bytesWritten = channel.write(buffers);

           注意在填充完数据后,一定要调用flip方法,不然通道是读不到数据的。

    package com.nio.channel;


    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.nio.ByteBuffer;
    import java.nio.channels.GatheringByteChannel;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Random;


    public class Marketing {


    private static final String DEMOGRAPHIC = "blahblah.txt";

    /**
    * @param args
    * @throws Exception 
    */
    public static void main(String[] args) throws Exception {
    // TODO Auto-generated method stub
    int reps = 10;
    if(args.length > 0) {
    reps = Integer.parseInt(args[0]);
    }

    FileOutputStream fos = new FileOutputStream(DEMOGRAPHIC);
    GatheringByteChannel gatherChannel = fos.getChannel();
    ByteBuffer[] bs = utterBS(reps);
    while(gatherChannel.write(bs) > 0) {

    }
    System.out.println();
    fos.close();
    }

    private static String[] col1 = {
    "Aggregate","Enable","Leverage",
    "Facilitate", "Synergize","Repurepose",
    "Strategize","collaborative","integrated"
    };
    private static String[] col2 = {
    "croll-platform", "best-of-head","frictionless",
    "ubiquitous","extensible","compelling",
    "mission-critical","collaborative","integrated"
    };
    private static String[] col3 = {
    "methodologies", "infomediaries","platforms",
    "schema","mindshare","paradigms",
    "functionalities","webservices","infrastructures"
    };

    private static String newline = System.getProperty("line.separator");
    private static ByteBuffer[] utterBS(int howMany) throws Exception {
    List list = new LinkedList();
    for(int i = 0; i < howMany; i++) {
    list.add(pickRandom(col1," "));
    list.add(pickRandom(col2, " "));
    list.add(pickRandom(col3, " "));
    }
    ByteBuffer[] bufs = new ByteBuffer[list.size()];
    list.toArray(bufs);
    return bufs;
    }


    private static Random rand = new Random();

    private static ByteBuffer pickRandom(String[] strings, String suffix) throws Exception {
    String string = strings[rand.nextInt(strings.length)];
    int total = string.length() + suffix.length();
    ByteBuffer buf = ByteBuffer.allocate(total);
    buf.put(string.getBytes("UTF-8"));
    buf.put(suffix.getBytes("UTF-8"));
    buf.flip();
    return buf;
    }
    }

    展开全文
  • 但是并不所有的浏览器都支持websocket特性,故为了磨平浏览器间的差异,为开发者提供统一的接口,引入了socket.io模块。在不支持websoket的浏览器中,socket.io可以降级为其他的通信方式,比如有AJAX long polli
  • NIO(Non-blocking IO一种同步非阻塞支持面向缓冲的,基于通道的I/O,也是IO多路复用的基础,主要解决高并发 或者 处理海量连接,IO处理问题 IO模式 所有的IO模式都分为两个阶段, 一等待就绪(准备数据)...

    NIO基础

    NIO(Non-blocking IO) 是一种同步非阻塞支持面向缓冲的,基于通道的I/O,也是IO多路复用的基础,主要是解决高并发 或者 处理海量连接,IO处理问题

    IO模式

    所有的IO模式都分为两个阶段, 一是等待就绪(准备数据)也就是从网卡copy到内核缓存区(从内核缓存区copy到网卡), 二是真正的操作(读,写) 也就是从内核缓存区copy到用户地址空间;

    IO模式 等待就绪阶段 是否阻塞 读写、拷贝阶段 是否阻塞
    BIO (Blocking IO)
    NIO(Non-blocking IO)
    AIO(Async IO)

    NIO工作模式:

    1. NIO主要有几个事件,包括读就绪,写就绪, 新连接到来, 当有新事件操作时,首先把事件注册到对应的处理器;
    2. 并由一个线程不断循环等待,调用操作系统底层的函数select() 或者 epoll(Linux 2.6之前是select、poll,2.6之后是epoll,Windows是iocp),并负责向操作系统查询IO是否就绪(标记:从网卡已经拷贝到内核缓存区,准备就绪),如果就绪执行事件处理器(从内核缓存区到用户内存)

    select 与 epoll的区别:

    1、每次调用select,都要把fd_set(加入文件描述符至集合)从用户态拷贝到内核态,fd_set很大时这是费时操作
    2、每次调用select,内核态都要遍历fd_set,fd_set很大时这是费时操作, epoll 如果准备就绪,系统回调通知,有个回调函数;
    3、select支持的文件描述符数量太小,默认是1024, epoll没有限制(系统最大的文件句柄数)

    NIO存在的问题

    1. 使用NIO != 高性能,当连接数<1000,并发程度不高或者局域网环境下NIO并没有显著的性能优势。
    2. NIO并没有完全屏蔽平台差异,它仍然是基于各个操作系统的I/O系统实现的,差异仍然存在。使用NIO做网络编程构建事件驱动模型并不容易,陷阱重重

    主从reactor

    架构

    Service:服务器的抽象
    MasterReactor:主reactor,负责监听网络端口FD状态(linux使用epoll,LT或者ET))
    SlaveReactor:从reactor,负责监听文件FD的IO ready时间、处理connection
    connection:TCP会话抽象,保持着request和response的socket FD
    handler:处理函数,结果可以同步返回,也可以通过channel移步通知给SlaveReactor,这里采用异步调用
    主从reactor-服务端

    实现

    nio/nio.go

    package nio
    
    import (
    	"fmt"
    	"net"
    )
    
    // 定义实体
    type MasterReactor struct {
    	net.Listener
    }
    
    type SlaveReactor struct {
    	h func(net.Conn)
    	buf chan struct{}
    }
    
    func (s *SlaveReactor)Handle(conn net.Conn) {
    	 s.buf <- struct{}{}
    	 go func(){
    		s.h(conn)
    		<-s.buf
    	}()
    }
    
    // 定义 construction method
    func NewMaster(l net.Listener) MasterReactor{
    	return MasterReactor{l}
    }
    func NewSlave(fn func(net.Conn), bufSize int) SlaveReactor {
    	return SlaveReactor{h: fn, buf: make(chan struct{}, bufSize)}
    }
    
    // 定义 handler method, 这个是一个echo method
    func HandleConn(conn net.Conn) {
    	defer conn.Close()
    	packet := make([]byte, 1024)
    	// 如果没有可读数据,也就是读 buffer 为空,则阻塞
    	_, _ = conn.Read(packet)
    	// 同理,不可写则阻塞
    	_, _ = conn.Write(packet)
    }
    
    func Service() {
    	listen, err := net.Listen("tcp", ":8089")
    	if err != nil {
    		fmt.Println("listen error: ", err)
    		return
    	}
    	
    	master := NewMaster(listen)
    	slave := NewSlave(HandleConn, 1024)
    	
    	for {
    		conn, err := master.Accept()
    		if err != nil {
    			fmt.Println("accept error: ", err)
    			break
    		}
    
    		// start a new goroutine to handle the new connection
    		slave.Handle(conn)
    	}
    }
    

    测试

    nio/nio_test.go

    package nio
    
    import (
    	"fmt"
    	"os"
    	"os/exec"
    	"testing"
    	"time"
    )
    
    func TestService(t *testing.T) {
    	go Service()
    	time.Sleep(3*time.Second)
    	fmt.Println(string(CUrlPOST()))
    }
    
    func CUrlPOST() []byte{
    	cmd := exec.Command("/bin/sh", "-c", `curl -X POST 'http://127.0.0.1:8089' --data "hello world"`)
    	resp, err := cmd.Output()
    	if err != nil {
    		fmt.Println("Output error ",err, resp)
    		os.Exit(1)
    	}
    	return resp
    }
    
    POST / HTTP/1.1
    Host: 127.0.0.1:8089
    User-Agent: curl/7.64.1
    Accept: */*
    Content-Length: 11
    Content-Type: application/x-www-form-urlencoded
    
    hello world
    
    
    展开全文
  • 本项目一款完整的 8 端口 IO-Link 主控器参考设计,其采用两个 LTC2874 四通道主控器以实现IO-Link v1.1 物理接口 (PHY),并利用了 LTC2874 的高端口数和坚固性 - 热插拔 (Hot Swap:trade_mark:) 保护型 L+ ...
  • 1、IO是面向流的,NIO面向缓冲的; 2、IO是阻塞的,NIO是非阻塞的; 3、IO是单线程的,NIO 通过选择器来模拟多线程的; 1. 通道 通道 Channel 对原 I/O 包中的流的模拟,可以通过它读取和写入数据。 通道与...
  • BIO(BIO阻塞的,多个怎么获取操作通道传来的信息?创建多个线程。线程创建太多,会导致cpu频繁晶振切换线程执行,影响效率不好,根本原因不是线程,而是阻塞) NIO(非阻塞的,你不必等待,那么一个线程就可以了,...
  • 套接字在传统上大多数实时聊天系统架构的解决方案,它提供客户机和服务器之间的双向通信通道。这意味着服务器可以向客户端推送消息。每当您编写一个聊天消息时,其思想服务器将获得它并将其推给所有其他连接的客
  • // 对每一个通道句柄实例来说,当它进行在读写操作时,代码必须维持通道的当前状态 // 这个可以用DataRead这个变量数组来实现.当我们确定了管道的当前状态,代码能够 // 确定下一个I/O操作什么 BOOL DataRead[ NUM_...
  • NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的块,所以NIO的效率要比IO高很多。 NIO即New IO,这个库在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的块,所以NIO...
  • 介绍通道 通道是一个对象,表示与硬件设备,文件,网络套接字,应用程序组件或其他能够执行写入,读取和其他I / O操作的实体的开放连接。 通道有效地在字节缓冲区和基于操作系统的I / O服务源或目标之间传输数据。...
  • PS: 之前一直想了解这个NIO到底什么东西,奈何目前用不到,听说现在许多框架都在用,而且面试的时候也有被问道,感觉还是去多了解了解底层怎么实现的~~这我的第100篇博客!!! 一. NIO与IO区别 NIO主要有三大核心部分...
  • 某些音频双方对话,有可能需要对音频作通道的分离。 示例代码如下: """ 音频双通道分离 """ import sys import numpy as np from scipy.io import wavfile from converter import mp3_to_wav def split_...
  • Java通道(Channel)的实现及优势

    万次阅读 2019-01-12 18:55:25
    通道(Channel):  由java.nio.channels包定义的,Channel表示IO源与目标打开的连接,Channel类似于传统的“流”,只不过Channel本身...通道是访问IO服务的导管,通过通道,我们可以以最小的开销来访问操作系统的...
  • MQTT中继节点的实现,该节点在具有足够可用GPIO的ESP8266 ESP-03模块或其他变体上本机运行。 此外,现在可以使用ESP12 ESP8266模块进行硬件设计。 请参考我的esp12-appliance-mod项目。 使用下面引用的工具链...
  • 我的ESP8266-MQTT-io-node项目的硬件实现。 特征: 提供一个双稳态闭锁继电器通道。 提供了用于链接LED和本地按钮的连接器,以锁定和解锁继电器。 双电压隔离电源安装在闩锁继电器的顶部。 该继电器能够在250...
  • IO vs Nio

    2019-08-08 10:16:03
    1.IO只能实现阻塞式的网络通信。NIO能够实现非阻塞的网络通信.(废话) 2.标准IO基于字节/字符流进行操作;而NIO是基于通道(Channel)进行操作的。(话说,通往女人心灵的通道是xxx道...) 3.流的读写通常是单向的,要么...
  • 初识IO

    2015-12-14 01:06:04
    刚刚接触IO流,感觉IO流就是构建两个通道,通过这两个通道获取内容和输出内容,由此可见IO很重要的。 比如说制作出文件搜索器,完成文件的复制粘贴,都通过IO流而实现的。虽然说文件搜索器是IO学习的内容,...
  • IO 什么流(Stream),流就是一系列的数据 当不同的介质之间有数据交互的时候,JAVA就使用流来实现。 数据源可以文件,还可以数据库,网络甚至其他的程序 比如读取文件的数据到程序中,站在程序的角度来看,就...
  • 各种io及其区别

    2020-06-09 21:50:03
    NIO:new IO同步非阻塞IO传统IO的升级,客户端和服务端通过channel(通道)通讯,实现了多路复用。 AIO:Asynchronous IO是NIO的升级,也叫NIO2,实现了异步非堵塞IO,异步IO的操作基于事件和回调机制。 ...
  • 【javaIOIO流的介绍

    2020-04-02 22:21:05
    IO—02IO的流的介绍 一、IO流的概念 流一组有顺序的,有起点和终点的...* java中所有的传统的流的形式都在java.io的包下,用于实现输入和输出功能 二、流的分类 1、按 流的方向 分 输入流:只能从中读取数据,不能...
  • Java之IO

    2019-05-06 22:49:00
    生活中,流有水流,河流等,它们是通过水管或者是河渠等管道...Java中IO是实现输入,输出的基础,可以方便的实现数据的输入和输出。 Java的IO流中常用到的一些类有,File,InputStream,OutputStream,FileInput...
  • Java IO

    2020-07-07 17:57:34
    在外设和JVM内存之间建立一个数据传输通道(数据传输通道是在创建流对象时创建的)。 让数据在通道上流动起来。 二.分类: 1.按I/O流的方向分类: 输入流:从外设传入内存,读取数据(read) 输出流:从内存输出外设...
  • Java IO

    2020-04-09 15:51:22
    流的概念和作用 1、流的定义:代表任何有能力产出数据的数据源对象或者有能力接受数据的接收端对象。...一、IO采用的实现模式:使用Decorator(装饰者)模式 二、IO的分类 1、按数据流的方向分为输入、输出...
  • IO流介绍

    2021-06-08 13:54:04
    流毕竟一个管道,这个内存和硬盘之间的通道,用完之后一定要关闭, 不然会耗费(占用)很多资源。养成好习惯,用完流一定要关闭。 所有的输出流都实现了: java.io.Flushable接口,都可刷新的,都有...
  • socket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道实现数据的互相传递。 我们知道网络 通信 都 基于 ip+port(套接字) 方能定位到目标的具体机器上的具体服务,操作系统有0-65535...
  • 79IO方式

    2021-05-21 08:37:33
    输入输出系统弄实现主机与IO设备之间的数据传输,可以采用不同的控制方式,各种方式在代价、性能、解决问题的着终点方面个不同,常用的IO方式有程序查询、程序中断、DMA和通道等方式,其中前两种更依赖CPU中程序指令...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 697
精华内容 278
关键字:

io通道是实现