NIO 看破也说破(一)—— Linux/IO 基础
Tips:
Linux底层通过文件的方式实现IO
Java等高级语言是通过syscall对Linux系统函数进行调用来实现网络通信
知识准备
Linux中一切类型都被抽象成文件,如:普通文件、目录、字符设备、块设备、套接字等
内存被划分为内核态和用户态,数据在用户态和内核态之间拷贝,内核态可以访问用户态数据,反之不可以
只有内核可以操作硬件资源(网卡、磁盘等),内核提供syscall函数
文件描述符
文件描述符是内核创建的方便管理已打开文件的索引,指代被打开的文件。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。
所有执行I/O操作的系统调用都通过文件描述符
在Linux系统中,ssh方式登录后查看/proc下信息,可以看到系统为每一个进程默认创建0,1,2 三个fd
用户态和内核态
内存被划分为内核态和用户态,数据在用户态和内核态之间拷贝,内核态可以访问用户态数据,反之不可以
用户态无法直接访问磁盘、网卡等设备,必须通过系统提供的syscall方式调用系统函数
系统调用
我们来执行如下Java代码,看看系统会发生什么:
利用strace获取系统函数调用栈:
查看生成的文件,找到关键信息行:
这里出现了3个系统函数,socket,bind,listen。我们分别查看Linux手册:
socket
socket() 为通信提供一个终点并且返回一个文件描述符fd,否则返回 -1
bind
bind(),接受三个参数(socket返回的文件描述符,socket地址结构体,socket地址长度),成功返回0
listen
listen(),接受两个参数(socket返回的文件描述符,接受socket队列的大小),成功返回0,失败返回-1
重新来看三个函数调用的关系,应该是:
查看Java进程下的文件描述符:
可以得出以下结论:
1、Java中通过对系统的调用来实现网络IO
2、ServerSocket server = new ServerSocket(8080); 一行Java代码的背后,经过了多个系统函数调用
3、实现网络IO,不是Java的能力,是操作系统内核提供的能力
备忘录
Linux中都是文件描述符
用户空间的程序,通过调用系统函数来访问操作系统软硬件资源
提供网络IO能力的不是Java/Python高级语言而是Linux Kernel
系列
关注我
如果您在微信阅读,请您点击链接 关注我 ,如果您在 PC 上阅读请扫码关注我,欢迎与我交流随时指出错误
版权声明: 本文为 InfoQ 作者【小眼睛聊技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/0e36ad9712c8d9ad8f7a7c570】。文章转载请联系作者。
评论 (7 条评论)