zoukankan      html  css  js  c++  java
  • 【深入剖析Tomcat笔记】第二篇 ServerSocket模型

    Socket 网络模型结构

    不同网络间的主机要进行消息交互时,这时我们就需要用到socket了,socket基于TCP/IP协议。

    图片来自《TPC/IP协议详解卷一》
    TCP/IP协议

    上图是TCP/IP四层网络模型,而socket所处位置在于
    Socket网络模型

    Socket主要是对TCP/IP基本网络结构的抽象整合,socket整体对运输层、网络层和链路层进行封装,使得基于Socket开发不必关心下层实现,并且开发者可以基于自己需求,自由选择网络传输协议,如:HTTP、RPC、SMTP等。

    DEMO

    DemoSocket

    public class DemoSocket {
    
        public static void main(String[] args) {
            try {
                Socket socket = new Socket("localhost", 8080);
                InputStream inputStream = socket.getInputStream();
    
                //输出IO流
                OutputStream outputStream = socket.getOutputStream();
                PrintWriter pw = new PrintWriter(new OutputStreamWriter(outputStream), true);
                pw.println("Hello Tomcat!");
    
                StringBuffer requestResult = new StringBuffer();
                byte[] bytes = new byte[1024];
                while(inputStream.read(bytes) != -1) {
                    String s = new String(bytes);
                    System.out.println(s);
                    requestResult.append(s);
                }
                System.out.println(requestResult);
                Thread.currentThread().sleep(50);
    
    
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    DemoServer

    private final static String REQUEST_SUCCESS = "HTTP/1.1 200 OK
    " +
                "Content-Type: text/html
    " +
                "
    " +
                "请求成功" ;
    
        public static void main(String[] args) {
            try {
                //创建SocketServer
                ServerSocket serverSocket = new ServerSocket(8080, 1, InetAddress.getByName("localhost"));
                boolean stop = false;
                while(!stop) {
                    //获取Socket
                    Socket socket = serverSocket.accept();
                    InputStream inputStream = socket.getInputStream();
                    OutputStream outputStream = socket.getOutputStream();
    
                    //读取请求数据
                    StringBuffer requestInfo = new StringBuffer();
                    byte[] bytes = new byte[1024];
                    if(inputStream.read(bytes) != -1) {
                        String s = new String(bytes);
                        System.out.println(s);
                        requestInfo.append(s);
                    }
                    System.out.println("Request Info:" + requestInfo);
    
                    //输出结果数据
                    outputStream.write(REQUEST_SUCCESS.getBytes());
    
                    socket.close();
    
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

    加了注释,理解不难

    Demo测试

    先运行DemoServer,再运行DemoSocket即可
    DemoServer运行结果
    DemoServer运行结果
    DemoSocket运行结果
    DemoSocket运行结果

    页面测试这里写图片描述

    分析

    基于Socket模型,我们已经简单实现了一个 服务,但还称不上服务容器。
    ServerSocket主要是对端口进行监听,并获取对应Socket连接,以下是Socket主要使用到的方法

    public ServerSocket(int port,                            //端口0到65535
                        int backlog,                         //等待队列大小
                        @Nullable InetAddress bindAddr)      //绑定地址
    
    public void bind(SocketAddress endpoint, int backlog)   //绑定地址,InetAddress是SocketAddress子类
    
    public Socket accept()                                  //监听并获Socket
    
    
    public void close()                                     //关闭ServerSocket

    Socket主要是承担网络连接工作,一下是Socket的主要方法

    public Socket(String host, int port)                    //创建Socket连接
    
    public Socket(Proxy proxy)                              //基于代理模式的Socket连接,Dubbo中的代理模式基于这种方式,核心都基于Socket
    
    public InputStream getInputStream()                     //读取Socket输入流
    
    public OutputStream getOutputStream()                   //读取Socket输出流

    核心使用到的类就是以上两个类,但是我们也发现了一些问题:

    • 基于io流的输入,效率很差并且对于unicode支持不是很好
    • 在SocketServer端,连接和解析在一起,这样会造成资源的浪费。解析层的对象创建会造成性能开销
    • 在设计层面,不能很好的兼容多种协议
    • 可配置性差
    • 异常机制不够完善
    • 等等

    在下一篇开始我们会逐渐开始解决这些问题

  • 相关阅读:
    java native方法
    linux free命令
    gdb使用
    java锁——wait,notify,synchronized
    java面试——问题回溯
    (转)每天一个linux命令(44):top命令
    java面试——jvm
    java面试——多线程
    数据库面试总结
    CMakeLists.txt使用
  • 原文地址:https://www.cnblogs.com/cunchen/p/9464121.html
Copyright © 2011-2022 走看看