Java粗浅认识-网络编程(一)

网络通信

网络通信,就是进程间的一种通信方式,网络通信都采用客户端-服务端模型,当然与之相对的就是进程内部的通信(就是后面要讲的多线程编程里面的东西,包括同步,信号量)。

client-server模型

unix网络通信关于网络通信

I/O多路复用select(基于轮询,支持少数文件描述符)、poll(基于轮询,支撑大量文件描述符)、epoll(系统计算文件描述数量,基于回调)

select 在初始化时,指定描述符容量大小,FD_SETSIZE的值上限在不同平台上运行是不一致的windows上是64(WINSOCK.H文件中定义)和linux(ulimit -a 查找open files 项)上受限于每个进程打开的最大文件个数(默认1024)

winsock.h文件中定义

winsock.h

linux fd限制

linux fd限制
linux open files限制


这里的select 函数 后来有pselect函数支持纳秒级别超时等待

poll 在初始化时,传入的第一个参数是一个链表,表示支持的文件描述,意味着受限于内存大小

select和poll都是在每次调用监听文件描述符时,是通过轮询来遍历,随着连接数量的增加,性能会下降

epoll,基于select和poll的缺点在2.6内核中引入,epoll中epoll_create(int size)中的size不是最大值,是一个估算值,系统会动态计算出真正的值,甚至在之后的更新中,只要是个整数就行
epoll_ctl(),控制文件描述的添加、删除,文件描述符感兴趣的事件注册和更改,就是一个回调机制。在epoll_ctl中传入的事件event.events是一个枚举类型,通过|符号来添加监听事件,其中如果添加了EPOLLET,设置关联的fd为ET的工作方式(水平触发事件立即返回结果)默认工作方式是LT(边缘触发事件,等待处理完毕后返回结果)。

I/O复用,理解I/O复用,就要理解,I/O没有复用的情况,多个连接同时请求一个服务,服务就排队一个一个处理,为了解决这个问题,就提出了I/O复用,通过上面讲解的select,poll,epoll 来统一接收请求,分发任务(select、poll)或主动处理,任务结束后通知(epoll回调)来解决。

网络通信模型

单进程模式

父进程接收到请求,fork子进程来处理,处理完毕了关闭子进程,缺点是,每次都要fork新的子进程出来,开销大

preforking改进

提前fork一个子进程池,父进程接收到请求,直接使用闲置的子进程

单线程模式

进程接收到请求,直接创建一个线程,就是每个请求,对应一个线程

prethreading改进

服务器启动时,预先创建一个线程池,服务器接收到请求,使用闲置的线程处理,不用临时创建新线程

Reactor,反应堆(I/O多路复用+线程池)

一个线程(进程)或线程池(进程池)每当Reactor(s)接受到一个请求时,就分配任务给其他线程或线程池处理,其中Netty采用多Reactor(接受)多线程(处理)模式

Proactor(异步网络模型)

每个请求来时,Proactor构造器负责创建Proactor时,同时也会创建对应的Handler回调,异步处理器(内核中)把Proactor和Handler同时注册到内核当中,异步处理器完成I/O后就会通知Proactor,proactor就会回调相应的Handler
说来比较拗口,简单点讲就是内核异步处理I/O操作,通知Proactor,proacor回调handler,linux下的异步网络模型就通过Reactor+epoll模拟出来的。

总结,网络编程模型讲解到此结束,接下里会一一通过Java代码展示讲解单线程模型prethreadingreactorproactor

猜你喜欢

转载自blog.csdn.net/bpz31456/article/details/85118911