Java IO
文章平均质量分 93
JavaIO相关的文章
fedorafrog
这个作者很懒,什么都没留下…
展开
-
KeepAlive详解
1. 什么是KeepAlive?首先,我们要明确我们谈的是TCP的 KeepAlive 还是HTTP的 Keep-Alive。TCP的KeepAlive和HTTP的Keep-Alive是完全不同的概念,不能混为一谈。实际上HTTP的KeepAlive写法是Keep-Alive,跟TCP的KeepAlive写法上也有不同。 TCP的keepalive是侧重在保持客户端和服务端的连接,一方会不定期发送心跳包给另一方,当一方端掉的时候,没有断掉的定时发送几次心跳包,如果间隔发送几次,对方都返回的是RST转载 2021-03-23 10:22:35 · 1192 阅读 · 0 评论 -
HTTP和HTTPS
1. 前言近几年,互联网发生着翻天覆地的变化,尤其是我们一直习以为常的HTTP协议,在逐渐的被HTTPS协议所取代,在浏览器、搜索引擎、CA机构、大型互联网企业的共同促进下,互联网迎来了“HTTPS加密时代”,HTTPS将在未来的几年内全面取代HTTP成为传输协议的主流。读完本文,希望你能明白:HTTP通信存在什么问题 HTTPS如何改进HTTP存在那些问题 HTTPS工作原理是什么2. 什么是HTTPSHTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安转载 2021-02-23 15:39:35 · 45993 阅读 · 5 评论 -
TCP中的NO_DELAY
1. TCP网络优化的两种机制TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、全双工、基于字节流的传输层通信协议,由IETF的RFC 793定义。TCP协议是网络编程中最重要的协议之一,TCP协议将上层的数据附上TCP报头等信息,封装成一个个报文段(segment),然后交由下层网络层去处理。TCP协议定义了TCP报文段的结...转载 2020-02-22 20:11:35 · 2582 阅读 · 0 评论 -
三次握手和四次挥手
1. 报文解析序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。 确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一...转载 2020-02-22 19:58:00 · 134 阅读 · 0 评论 -
C10K问题及解决方案
1.C10K问题大家都知道互联网的基础就是网络通信,早期的互联网可以说是一个小群体的集合。互联网还不够普及,用户也不多。一台服务器同时在线100个用户估计在当时已经算是大型应用了。所以并不存在什么C10K的难题。互联网的爆发期应该是在www网站,浏览器,雅虎出现后。最早的互联网称之为Web1.0,互联网大部分的使用场景是下载一个Html页面,用户在浏览器中查看网页上的信息。这个时期也不存在C10K问题。Web2.0时代到来后就不同了,一方面是普及率大大提高了,用户群体几何倍增长。另一方面是互联网不.转载 2021-02-22 11:27:07 · 730 阅读 · 0 评论 -
高性能网络编程(七)TCP连接的内存使用
当服务器的并发TCP连接数以十万计时,我们就会对一个TCP连接在操作系统内核上消耗的内存多少感兴趣。socket编程方法提供了SO_SNDBUF、SO_RCVBUF这样的接口来设置连接的读写缓存,linux上还提供了以下系统级的配置来整体设置服务器上的TCP内存使用,但这些配置看名字却有些互相冲突、概念模糊的感觉,如下(sysctl -a命令可以查看这些配置):net.ipv4.tcp_rmem = 8192 87380 16777216net.ipv4.tcp_wmem = 8192 65536转载 2021-02-18 16:49:46 · 533 阅读 · 1 评论 -
高性能网络编程(六)reactor反应堆与定时器管理
反应堆开发模型被绝大多数高性能服务器所选择,上一篇所介绍的IO多路复用是它的实现基础。定时触发功能通常是服务器必备组件,反应堆模型往往还不得不将定时器的管理囊括在内。本篇将介绍反应堆模型的特点和用法。首先我们要谈谈,网络编程界为什么需要反应堆?有了IO复用,有了epoll,我们已经可以使服务器并发几十万连接的同时,维持高TPS了,难道这还不够吗?我的答案是,技术层面足够了,但在软件工程层面却是不够的。程序使用IO复用的难点在哪里呢?1个请求虽然由多次IO处理完成,但相比传统的单线程完整处理请求生转载 2021-02-18 16:45:46 · 348 阅读 · 0 评论 -
高性能网络编程(五)IO复用与并发编程
对于服务器的并发处理能力,我们需要的是:每一毫秒服务器都能及时处理这一毫秒内收到的数百个不同TCP连接上的报文,与此同时,可能服务器上还有数以十万计的最近几秒没有收发任何报文的相对不活跃连接。同时处理多个并行发生事件的连接,简称为并发;同时处理万计、十万计的连接,则是高并发。服务器的并发编程所追求的就是处理的并发连接数目无限大,同时维持着高效率使用CPU等资源,直至物理资源首先耗尽。并发编程有很多种实现模型,最简单的就是与“线程”捆绑,1个线程处理1个连接的全部生命周期。优点:这个模型足够简单,它可以实转载 2021-02-18 16:44:11 · 334 阅读 · 0 评论 -
高性能网络编程(四)TCP连接的关闭
TCP连接的关闭有两个方法close和shutdown,这篇文章将尽量精简的说明它们分别做了些什么。为方便阅读,我们可以带着以下5个问题来阅读本文:当socket被多进程或者多线程共享时,关闭连接时有何区别? 关连接时,若连接上有来自对端的还未处理的消息,会怎么处理? 关连接时,若连接上有本进程待发送却未来得及发送出的消息,又会怎么处理? so_linger这个功能的用处在哪? 对于监听socket执行关闭,和对处于ESTABLISH这种通讯的socket执行关闭,有何区别?下面分三部分进转载 2021-02-18 16:42:45 · 596 阅读 · 0 评论 -
高性能网络编程(三)TCP消息的接收
这篇文章将试图说明应用程序如何接收网络上发送过来的TCP消息流,由于篇幅所限,暂时忽略ACK报文的回复和接收窗口的滑动。为了快速掌握本文所要表达的思想,我们可以带着以下问题阅读:应用程序调用read、recv等方法时,socket套接字可以设置为阻塞或者非阻塞,这两种方式是如何工作的? 若socket为默认的阻塞套接字,此时recv方法传入的len参数,是表示必须超时(SO_RCVTIMEO)或者接收到len长度的消息,recv方法才会返回吗?而且,socket上可以设置一个属性叫做SO_RCVL转载 2021-02-18 16:38:34 · 952 阅读 · 0 评论 -
高性能网络编程(二)TCP消息的发送
在上一篇中,我们已经建立好的TCP连接,对应着操作系统分配的1个套接字。操作TCP协议发送数据时,面对的是数据流。通常调用诸如send或者write方法来发送数据到另一台主机,那么,调用这样的方法时,在操作系统内核中发生了什么事情呢?我们带着以下3个问题来细细分析:发送方法成功返回时,能保证TCP另一端的主机接收到吗? 能保证数据已经发送到网络上了吗? 套接字为阻塞或者非阻塞时,发送方法做的事情有何不同?要回答上面3个问题涉及了不少知识点,我们先在TCP层面上看看,发送方法调用时内核做了哪些事。我转载 2021-02-18 16:21:06 · 567 阅读 · 0 评论 -
高性能网络编程(一)
1. 开篇最近在部门内做了个高性能网络编程的培训,近日整理了下PPT,欲写成一系列文章从应用角度谈谈它。编写服务器时,许多程序员习惯于使用高层次的组件、中间件(例如OO(面向对象)层层封装过的开源组件),相比于服务器的运行效率而言,他们更关注程序开发的效率,追求更快的完成项目功能点、希望应用代码完全不关心通讯细节。他们更喜欢在OO世界里,去实现某个接口、实现这个组件预定义的各种模式、设置组件参数来达到目的。学习复杂的通讯框架、底层细节,在习惯于使用OO语言的程序员眼里是绝对事倍功半的。以上做法无可厚转载 2021-02-07 17:16:37 · 619 阅读 · 0 评论 -
Java的Direct Memory与IO
ByteBuffer的源码中有这样一段注释:A byte buffer is either direct or non-direct. Given a direct byte buffer, the Java virtual machine will make a best effort to perform native I/O operations directly upon it. That is, it will attempt to avoid copying the buffer's co转载 2021-02-02 19:58:00 · 297 阅读 · 1 评论 -
跟踪三个文件IO方法的调用链
1.FileInputStream.read最朴素的方法就是先申请一段byte数组作为缓冲区,然后调用FileInputStream.read方法把文件里的数据灌到缓冲区中,代码如下所示FileInputStream reader = new FileInputStream(fileName);byte[] buf = new byte[1024 * 64];//在heap memory中开辟一块缓冲区while (reader.read(buf) != -1) {//调用FileInput.转载 2021-02-02 19:55:48 · 258 阅读 · 0 评论 -
缓冲IO / 直接IO /内存映射mmap
1. 缓冲IO在介绍缓冲IO之前需要先了解一下常用的机械硬盘的原理与特点:一个机械硬盘中装有多个盘片,每个盘片上有多个同心圆(磁道),每个同心圆又由多个弧(扇区)组成,每个弧上都记录了等量的数据(比方说512byte)如果发起一个随机读写请求,磁头需要先找到对应的磁道,然后等待对应的扇区旋转到磁头正下方才能开始读取数据(民用机械硬盘的转速一般在5400或者7200RPM,工业界倒是经常使用10000RPM的机械硬盘。但是它们的寻道时间大概都在几ms到十几ms左右)机械硬盘的顺序读写很快(一般转载 2021-02-02 16:04:03 · 1139 阅读 · 0 评论 -
JDK Epoll空轮询bug
前面讲到了epoll的一些机制,与select和poll等传统古老的IO多路复用机制的一些区别,这些区别实质可以总结为一句话,就是epoll将重要的基于事件的fd集合放在了内核中来完成,因为内核是高效的,所以很多关于fd事件监听集合的操作也是高效的,不方便的就是,因为在内核中,所以我们需要通过系统调用来调用关于fd操作集合,而不是直接自己攒一个。如果在linux中,epoll在JDK6中还需要配置,在后续的版本中为JDK的NIO提供了默认的实现,但是epoll在JDK中的实现却是漏洞百出的,bug非常的多,转载 2021-02-02 14:33:27 · 817 阅读 · 1 评论 -
Linux I/O 原理和 Zero-copy 技术(加深理解)
1. 导言如今的网络应用早已从 CPU 密集型转向了 I/O 密集型,网络服务器大多是基于C-S模型,也即客户端 - 服务端模型,客户端需要和服务端进行大量的网络通信,这也决定了现代网络应用的性能瓶颈:I/O。传统的 Linux 操作系统的标准 I/O 接口是基于数据拷贝操作的,即 I/O 操作会导致数据在操作系统内核地址空间的缓冲区和用户进程地址空间定义的缓冲区之间进行传输。设置缓冲区最大的好处是可以减少磁盘 I/O 的操作,如果所请求的数据已经存放在操作系统的高速缓冲存储器中,那么就...转载 2021-02-04 16:21:01 · 673 阅读 · 0 评论 -
Zero-Copy技术
1. 概述考虑这样一种常用的情形:你需要将静态内容(类似图片、文件)展示给用户。那么这个情形就意味着你需要先将静态内容从磁盘中拷贝出来放到一个内存buf中,然后将这个buf通过socket传输给用户,进而用户或者静态内容的展示。这看起来再正常不过了,但是实际上这是很低效的流程,我们把上面的这种情形抽象成下面的过程:read(file, tmp_buf, len);write(socket, tmp_buf, len);首先调用read将静态内容,这里假设为文件A,读取到tmp_buf, 然后转载 2021-02-02 11:29:07 · 180 阅读 · 0 评论 -
NIO相关基础篇
1.用户空间以及内核空间概念我们知道现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核,保证内核的安全,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3.转载 2021-02-02 11:18:41 · 169 阅读 · 0 评论