Jetty之SocketEndPoint分析
来源:互联网 发布:egd网络小黄金骗局 编辑:程序博客网 时间:2024/06/03 13:54
这里Endpoint的概念可以按字面来当成是端点吧,因为TCP通信是双工的,那么就存在着两个端点。。。
这里我们先来看看SocketEndPint的继承体系:
这个够简单的吧,这几就是直线型的,那么这里我们先来看看EndPoint接口的定义吧:
- //端点的定义
- public interface EndPoint
- {
- //关闭当前的端点
- void close() throws IOException;
- //读取数据,然后将其保存到buffer里面,返回表示实际读取的字节数目,-1表示已经读完了
- int fill(Buffer buffer) throws IOException;
- //将buffer里面的数据发送出去,返回实际发送的字节数目
- int flush(Buffer buffer) throws IOException;
- //连续写?
- int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException;
- //返回当前的本地地址ip
- public String getLocalAddr();
- //本地的主机名
- public String getLocalHost();
- //本地端口
- public int getLocalPort();
- //远程的ip地址
- public String getRemoteAddr();
- //远程的主机名字
- public String getRemoteHost();
- //远程的端口号
- public int getRemotePort();
- //是否是阻塞的
- public boolean isBlocking();
- //是否缓冲
- public boolean isBufferred();
- /* ———————————————————— */
- public boolean blockReadable(long millisecs) throws IOException;
- /* ———————————————————— */
- public boolean blockWritable(long millisecs) throws IOException;
- //是否已经打开
- public boolean isOpen();
- //返回底层的实现,是socket或者channel
- public Object getTransport();
- //是否有缓存的输入数据
- public boolean isBufferingInput();
- //是否有缓存的输出数据
- public boolean isBufferingOutput();
- //将缓存的输出全部输出
- public void flush() throws IOException;
- }
它主要定义了一些对数据操作的方法,例如flush和fill,其中flush将buffer通过底层发送出去,而fill用于从底层的连接读取数据,然后将其填充到buffer里面去。。。。
当然还有一些其他的方法,例如获取本地和远程的ip的地址什么的,不过总的来说还是很简单的。。。
那么接下来来看看StreamEndPoint的定义吧,它是一个抽象类,实现了EndPoint中的大多数方法:
- //基于流的endPoint
- public class StreamEndPoint implements EndPoint
- {
- InputStream _in; //输入流
- OutputStream _out; //输出流
- //构造函数
- public StreamEndPoint(InputStream in, OutputStream out) {
- _in=in;
- _out=out;
- }
- //是否是阻塞的,是
- public boolean isBlocking(){
- return true;
- }
- public boolean blockReadable(long millisecs) throws IOException {
- return true;
- }
- public boolean blockWritable(long millisecs) throws IOException {
- return true;
- }
- //是否已经打开
- public boolean isOpen(){
- return _in!=null;
- }
- //是否关闭
- public final boolean isClosed() {
- return !isOpen();
- }
- //关闭,说白了就是关闭底层的输入输出流
- public void close() throws IOException {
- if (_in!=null)
- _in.close();
- _in=null;
- if (_out!=null)
- _out.close();
- _out=null;
- }
- //从inputstream中读取数据,存到buffer里面
- public int fill(Buffer buffer) throws IOException {
- // TODO handle null array()
- if (_in==null)
- return 0;
- int space=buffer.space(); //当前buffer的空间
- if (space<=0)
- {
- if (buffer.hasContent())
- return 0;
- throw new IOException(“FULL”);
- }
- int len = buffer.readFrom(_in,space); //读取,space为最大值
- return len;
- }
- //将buffer里面的数据输出到outputstream
- public int flush(Buffer buffer) throws IOException {
- // TODO handle null array()
- if (_out==null)
- return -1;
- int length=buffer.length(); //当前buffer的自己数
- if (length>0)
- buffer.writeTo(_out);
- buffer.clear();
- return length;
- }
- //这里就姑且认为是连续写吧
- public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException {
- int len=0;
- if (header!=null)
- {
- int tw=header.length();
- if (tw>0)
- {
- int f=flush(header);
- len=f;
- if (f<tw)
- return len;
- }
- }
- if (buffer!=null)
- {
- int tw=buffer.length();
- if (tw>0)
- {
- int f=flush(buffer);
- if (f<0)
- return len>0?len:f;
- len+=f;
- if (f<tw)
- return len;
- }
- }
- if (trailer!=null)
- {
- int tw=trailer.length();
- if (tw>0)
- {
- int f=flush(trailer);
- if (f<0)
- return len>0?len:f;
- len+=f;
- }
- }
- return len;
- }
- //获取本地的ip地址,这里其实要留给子类来具体的实现
- public String getLocalAddr() {
- return null;
- }
- public String getLocalHost() {
- return null;
- }
- //获取本地的端口
- public int getLocalPort() {
- return 0;
- }
- public String getRemoteAddr() {
- return null;
- }
- public String getRemoteHost() {
- return null;
- }
- public int getRemotePort() {
- return 0;
- }
- public Object getTransport() {
- return null;
- }
- public InputStream getInputStream() {
- return _in;
- }
- public void setInputStream(InputStream in) {
- _in=in;
- }
- public OutputStream getOutputStream() {
- return _out;
- }
- public void setOutputStream(OutputStream out) {
- _out=out;
- }
- public void flush() throws IOException {
- _out.flush();
- }
- public boolean isBufferingInput() {
- return false;
- }
- public boolean isBufferingOutput() {
- return false;
- }
- public boolean isBufferred() {
- return false;
- }
- }
其实从类型的名字就能够看出,它是基于流的,那么它有两个属性inputStream和outputSteam就很正常了,那么它所实现的I/O操作都需要由他们来实现才可以。。。
而且上面具体的方法实现也都很简单,可以看看fill方法,无非就是从inputstream里读取数据然后保存到buffer里面。。。
那么最后我们来看看SocketEndPoint的定义吧:
- public class SocketEndPoint extends StreamEndPoint
- {
- Socket _socket;
- InetSocketAddress _local; //本地的地址
- InetSocketAddress _remote; //远程地址
- //构造函数
- public SocketEndPoint(Socket socket)
- throws IOException {
- super(socket.getInputStream(),socket.getOutputStream());
- _socket=socket;
- }
- //用于判断当前是否打开的,需要底层的socket打开的才表示打开的
- public boolean isOpen() {
- return super.isOpen() && _socket!=null && !_socket.isClosed() && !_socket.isInputShutdown() && !_socket.isOutputShutdown();
- }
- //说白了就是关闭底层的socket
- public void close() throws IOException {
- if (!_socket.isClosed() && !_socket.isOutputShutdown()) {
- try {
- _socket.shutdownOutput();
- }
- catch(IOException e) {
- Log.ignore(e);
- }
- catch(UnsupportedOperationException e) {
- Log.ignore(e);
- }
- }
- _socket.close();
- _in=null;
- _out=null;
- }
- //获取本地的地址
- public String getLocalAddr() {
- if (_local==null)
- _local=(InetSocketAddress)_socket.getLocalSocketAddress();
- if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
- return Portable.ALL_INTERFACES;
- return _local.getAddress().getHostAddress();
- }
- public String getLocalHost() {
- if (_local==null)
- _local=(InetSocketAddress)_socket.getLocalSocketAddress();
- if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
- return Portable.ALL_INTERFACES;
- return _local.getAddress().getCanonicalHostName();
- }
- //返回本地端口
- public int getLocalPort() {
- if (_local==null)
- _local=(InetSocketAddress)_socket.getLocalSocketAddress();
- return _local.getPort();
- }
- //返回远程的ip地址
- public String getRemoteAddr() {
- if (_remote==null)
- _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
- InetAddress addr = _remote.getAddress();
- return ( addr == null ? null : addr.getHostAddress() );
- }
- //返回远程的主机名
- public String getRemoteHost() {
- if (_remote==null)
- _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
- return _remote.getAddress().getCanonicalHostName();
- }
- //返回远程的端口地址
- public int getRemotePort() {
- if (_remote==null)
- _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
- return _remote.getPort();
- }
- //返回底层用于通信的socket
- public Object getTransport() {
- return _socket;
- }
- }
这个类从名字也都能看出个大概了,底层的连接用的是socket,那么父类中的stream直接从socket中获取就可以了,然后还是先了一些其他的方法,例如获取本地和远程的地址什么的。。。
看到这里觉得jetty的整个设计还是挺简练的。。。。
0 0
- Jetty之SocketEndPoint分析
- Jetty之SocketEndPoint分析
- jetty SocketEndPoint分析
- Jetty源码分析之AbstractHandler
- Jetty源码分析之ContextHandler
- Jetty源码分析之WebAppContext
- Jetty 源代码分析之线程池
- Jetty 源代码分析之NIO连接器
- Jetty源码分析之线程池:QueuedThreadPool
- Jetty分析
- Jetty 分析
- Jetty源码分析之ScopedHandler及Handler链
- Jetty源码分析之NIO实现的Connector:SelectChannelConnector
- jetty之嵌入式运行jetty
- Jetty 源码分析
- Jetty 源码分析(转移)
- Jetty 源码分析
- Jetty 源码分析
- 14. Longest Common Prefix\441. Arranging Coins\367. Valid Perfect Square
- Unity Physics2D.OverlapPointAll
- Codeforces Round #398 (Div. 2) C. Garland
- Notepad++ 插件整理
- Bullet 物理引擎学习笔记(1) -- HelloWorld 详解
- Jetty之SocketEndPoint分析
- RxJava笔记--02(Android中使用RxAndroid)
- 详解 Spotlight on Unix 监控Linux服务器
- ajax_ajax从json数据中取其中某一值,输出未定义
- Android自定义网络加载中对话框
- win7下electron安装
- jquery.validate file验证jpg图片的坑
- Android 热修复Demo
- html表单知识点