day10_网络

day10_网络

1网络传输模型

双方计算机转换数据的过程 和中间涉及的各层协议

image-20250806095301282

http协议 是应用层协议 规范应用程序之间发送数据的格式

基于TCP/IP协议簇

image-20250806102346582

OSI七层模型 和 tcp/ip四层模型

image-20250806102527175

OSI七层模型 是高度的抽象 每层都有众多的协议可选

tcp/ip四层模型 是一种网络模型的实现方式 主要保证数据传输的完整性

2网络名词介绍

网络应用程序模式

c/s 客户端 服务器

b/s 浏览器 服务器 用户部分 不需要主动更新 与硬件交互时效率较低 系统中对IO操作有限制

IP协议

通过IP地址标记计算机

IPV4版本 32位地址标记计算机 0.0.0.0 255.255.255.255

​ 127.0.0.1 回送地址 表示本机

​ 192.168.xxx.xxx 局域网专用地址

IPV6版本 128位地址标记计算机

子网掩码 组局域网时 判断是否同一网段

域名 为了地址好记 域名需要租用

DNS解析 域名与ip地址的转换

暗网 深网

传输层协议

把数据打成数据封包发送

TCP 保证数据的完整性

面向连接的 可靠链接

发送数据前 需要保证数据已建立

断开链接时 需要确认数据发送完毕才断开链接

image-20250806110708681

image-20250806110719866

UPD

面向无连接 不可靠链接

发送数据前 不需要保证数据已建立

发送完毕即结束

端口号 指定应用程序 解析和发送数据包

2000以下 系统级别端口

5000以下 知名应用程序

应用层协议

应用程序之间发送的字符格式

发送的数据 请求报文 request

返回的数据 响应报文 response

请求

image-20250806112120754

get方式 不需要填 默认传字符

post方式 需要指明 字符还是字节

Content-Type : application/x-www-form-urlencoded 字符

​ multi-part/formdata 字节

响应

image-20250806112131951

返回数据的格式和字符编码

Content-Type :text/html;charset=utf-8 返网页

​ application/json;charset=utf-8 返json字符串

不同文件 有不同的类型 让浏览器区分

响应码 常用响应码

200 OK 数据正常

400 Bad Request 请求url格式错误 有异常字符

403 Forbidden 拒绝访问

404 notfound 资源地址错误

405 Method Not Allowed 请求方式没匹配 服务器只处理get post传会出这个错误

500 Internal Server Error 服务器内部错误 代码有错

502 Bad Gateway 网关配置错误

503 Service Unavailable 服务器过载

http协议 浏览器与服务器交互时使用的主要协议

3java中网络API

URL

URL 统一资源定位符 只允许ascii字符 如果有特殊字符 标点符号 都需要做urlencode

http://   111.222.111.222   :   5555     /search   ?   name=jack&address=newstreet
协议          地址/域名            端口      资源地址         查询参数

URI 统一资源标识符 部分地址

/search   ?   name=jack&address=newstreet
package com.javasm.netdemo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

/**
 * @className: URLDemo
 * @description:
 * @author: gfs
 * @date: 2025/8/6 14:38
 * @version: 0.1
 * @since: jdk17
 */
public class URLDemo {
    public static void main(String[] args) {
        try {
            URL url = new URL("http://111.11.22.223:5567/sys/query?name=rose");
            //可以解析和读取正确的url格式
            System.out.println(url.getProtocol());
            System.out.println(url.getHost());
            System.out.println(url.getPort());
            System.out.println(url.getPath());
            System.out.println(url.getQuery());
            URL url2 = new URL("http://t.weather.itboy.net/api/weather/city/101010100");

            URLConnection urlConnection = url2.openConnection();
            //out   给别的程序写
            //in    别人给我写的
            //可以读取到响应体 的内容

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            String s = bufferedReader.readLine();
            System.out.println(s);
            //urlConnection.getInputStream()

            //HTTPClient

        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }
}

Socket ServerSocket

封装了TCP请求 可以让两个进程通过网络链接

client

package com.javasm.netdemo;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

/**
 * @className: ClientDemo
 * @description:
 * @author: gfs
 * @date: 2025/8/6 14:54
 * @version: 0.1
 * @since: jdk17
 */
public class ClientDemo {
    public static void main(String[] args) {

        //tcp链接
        //Socket 套接字

        /*
        * socket serverSocket
        * 1 通过 网络做数据传输
        * 2 基于tcp协议 不涉及应用层协议  可以自定义应用层协议
        * 3 什么叫应用层协议  规定了 应用程序之间传输数据的格式
        *
        * */

        /*
        * 浏览器 使用http协议               java程序 tcp做服务器端程序 也要使用http协议
        *                                 按http协议格式读请求
        *                                 按http协议格式写响应
        *
        * */


        try {
            Socket socket = new Socket("192.168.0.35",7890);

            OutputStream outputStream = socket.getOutputStream();
            //通过输出流向服务端 写数据
            DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
            //name:jack;age:15;address:第五大街
            //传java对象
            //dataOutputStream.writeUTF("name:jack;age:15;address:第五大街");
            dataOutputStream.writeUTF("aaaa");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }
}

server

package com.javasm.netdemo;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @className: ServerDemo
 * @description:
 * @author: gfs
 * @date: 2025/8/6 14:53
 * @version: 0.1
 * @since: jdk17
 */
public class ServerDemo {
    public static void main(String[] args) {
        //流数据的出入口
        try {
            ServerSocket serverSocket = new ServerSocket(7890);
            System.out.println("服务器启动 开始监听7890端口.......");
            //开始等待指定端口的数据
            Socket accept = serverSocket.accept();

            InputStream inputStream = accept.getInputStream();
            DataInputStream dataInputStream = new DataInputStream(inputStream);
            String personStr = dataInputStream.readUTF();
            //必须按照约定的格式拆分和解析
            //name:jack;age:15;address:第五大街
            System.out.println(personStr);
            String[] personPropArr = personStr.split(";");
            Person person = new Person();
            person.setName(personPropArr[0].split(":")[1]);
            person.setAge(Integer.valueOf(personPropArr[1].split(":")[1]) );
            person.setAddr(personPropArr[2].split(":")[1]);

            System.out.println(person.toString());

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

person

package com.javasm.netdemo;

/**
 * @className: Person
 * @description:
 * @author: gfs
 * @date: 2025/8/6 15:13
 * @version: 0.1
 * @since: jdk17
 */
public class Person {

    private String name;
    private Integer age;
    private String addr;

    public Person(String name, Integer age, String addr) {
        this.name = name;
        this.age = age;
        this.addr = addr;
    }
    public Person() {

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "Person对象{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", addr='" + addr + '\'' +
                '}';
    }
}

4服务器示例

image-20250806165729210

服务器代码示例

http包

MyRequest 请求输入流的解析 抽出关键数据 封装成对象

package com.javasm.myserver.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * @className: MyRequest
 * @description:
 * @author: gfs
 * @date: 2025/8/6 15:49
 * @version: 0.1
 * @since: jdk17
 */
public class MyRequest {
    private String method;
    private String url;

   //读请求报文 把关键数据从报文字符中抽取出来 封装成对象 方便使用
   public MyRequest(InputStream inputStram){
       //按照http协议格式读取
       BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStram));
       try {
           String reqLine = bufferedReader.readLine();
           String[] reqLineArr = reqLine.split(" ");
            method = reqLineArr[0];
            url = reqLineArr[1];
           //String 协议版本 = reqLineArr[2];


       } catch (IOException e) {
           throw new RuntimeException(e);
       }
   }

    public String getMethod() {
        return method;
    }

    public String getUrl() {
        return url;
    }
}

MyResponse 响应输出流 公共响应头

package com.javasm.myserver.http;

import java.io.OutputStream;

/**
 * @className: MyResponse
 * @description:
 * @author: gfs
 * @date: 2025/8/6 15:49
 * @version: 0.1
 * @since: jdk17
 */
public class MyResponse {
    private  OutputStream writer;
    public static final String respHeader = "HTTP/1.1 200 OK\r\n"+
                                             "Content-Type: text/html;charset=utf-8\r\n"+
                                             "\r\n";

    public MyResponse(OutputStream os){
        writer = os;
    }

    public OutputStream getWriter() {
        return writer;
    }
}

servlet包

MyServlet 作为服务代码类的标准

package com.javasm.myserver.servlet;

import com.javasm.myserver.http.MyRequest;
import com.javasm.myserver.http.MyResponse;

/**
 * @className: MyServlet
 * @description:
 * @author: gfs
 * @date: 2025/8/6 16:01
 * @version: 0.1
 * @since: jdk17
 */
public abstract class MyServlet {

    //每个具体的功能类中 可能会使用到请求和响应
    public abstract  void service(MyRequest req, MyResponse resp);
}

Login 具体的服务代码

package com.javasm.myserver.servlet;

import com.javasm.myserver.http.MyRequest;
import com.javasm.myserver.http.MyResponse;

import java.io.IOException;
import java.io.OutputStream;

/**
 * @className: Login
 * @description:
 * @author: gfs
 * @date: 2025/8/6 16:03
 * @version: 0.1
 * @since: jdk17
 */
public class Login extends MyServlet {

    @Override
    public void service(MyRequest req, MyResponse resp) {
        //可以做java的数据处理
        System.out.println("登录的代码处理");
        OutputStream writer = resp.getWriter();
        try {
            writer.write(MyResponse.respHeader.getBytes());
            writer.write("<h1>登录成功!!!!</h1>".getBytes());
            writer.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

Register 具体的服务代码

package com.javasm.myserver.http;

import java.io.OutputStream;

/**
 * @className: MyResponse
 * @description:
 * @author: gfs
 * @date: 2025/8/6 15:49
 * @version: 0.1
 * @since: jdk17
 */
public class MyResponse {
    private  OutputStream writer;
    public static final String respHeader = "HTTP/1.1 200 OK\r\n"+
                                             "Content-Type: text/html;charset=utf-8\r\n"+
                                             "\r\n";

    public MyResponse(OutputStream os){
        writer = os;
    }

    public OutputStream getWriter() {
        return writer;
    }
}

server包

MyServer 服务器加载配置文件 进核心容器 启动tcp监听 等待数据

package com.javasm.myserver.server;

import com.javasm.myserver.http.MyRequest;
import com.javasm.myserver.http.MyResponse;
import com.javasm.myserver.servlet.MyServlet;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * @className: MyServer
 * @description:
 * @author: gfs
 * @date: 2025/8/6 16:09
 * @version: 0.1
 * @since: jdk17
 */
public class MyServer {
    static Map<String, MyServlet> mapping = new HashMap<>();
    static Properties prop = new Properties();


    public static void serverInit(){
        //通过配置文件 加载核心容器
        //找服务器编译的根路径
        //MyServer.class.getResourceAsStream("/")
        try {
            prop.load(MyServer.class.getResourceAsStream("/mapping.properties"));
            System.out.println(prop);
            Set<Object> keys = prop.keySet();
            for(Object key: keys){
                if(key.toString().contains("url")){
                    String url = prop.getProperty(key.toString());
                    String classKey = key.toString().replace("url", "class");
                    String className = prop.getProperty(classKey);
                    System.out.println(url+"---"+className);

                    //通用的创建实例对象代码
                    //可以做对象强转
                    MyServlet ms =(MyServlet) Class.forName(className).getDeclaredConstructor().newInstance();
                    mapping.put(url,ms);

                }
            }
            System.out.println(mapping);

        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

    }

    public static void serverStart(){
        //接收请求 分发请求
        try {
            ServerSocket serverSocket = new ServerSocket(8890);
            System.out.println("服务器启动 开始监听8890端口......");
            while(true){

                /*
                * 1服务器需要能一直运行
                * 2服务器必须满足多线程 才可以支持多用户访问
                * */

                Socket accept = serverSocket.accept();
                Thread newThread = new MyProcess(accept);
                newThread.start();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }


    public static void main(String[] args) {
        MyServer.serverInit();
        MyServer.serverStart();
    }

}

mapping.properties 配置文件

servlet.one.url=/login
servlet.one.class=com.javasm.myserver.servlet.Login

servlet.two.url=/register
servlet.two.class=com.javasm.myserver.servlet.Register



servlet.thr.url=/user
servlet.thr.class=com.javasm.myserver.servlet.UserList


MyProcess 子线程代码

package com.javasm.myserver.server;

import com.javasm.myserver.http.MyRequest;
import com.javasm.myserver.http.MyResponse;
import com.javasm.myserver.servlet.MyServlet;

import java.net.Socket;

/**
 * @className: MyProcess
 * @description:
 * @author: gfs
 * @date: 2025/8/6 16:42
 * @version: 0.1
 * @since: jdk17
 */
public class MyProcess extends Thread {
    private Socket accept;

    public MyProcess(Socket accept){
        this.accept = accept;
    }

    @Override
    public void run() {
        try{
            MyRequest req = new MyRequest(accept.getInputStream());
            MyResponse resp = new MyResponse(accept.getOutputStream());
            // 读到请求报文的url req.getUrl()
            String currentUrl = req.getUrl();
            MyServlet currentServlet = MyServer.mapping.get(currentUrl);
            currentServlet.service(req,resp);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}

posted @ 2025-08-09 22:13  小胡coding  阅读(4)  评论(0)    收藏  举报