2022-08-11 第二小组 张明旭 学习记录

发布于:2023-01-21 ⋅ 阅读:(204) ⋅ 点赞:(0)

目录

心情日记

重点归纳

知识点

网络编程(网络通信)

Socket编程

同一网络环境下,如何访问其他主机?

怎么查看自己的IP地址

特点

Socket通信

UDP:不可靠的传输协议

面试题

URL工具类

InetAddress工具类

软件架构

web服务器

端口号自己定义,怎么获得IP地址?

重定向


心情日记

又要考试了,还是企业出题——大考。害怕。。。

重点归纳

  1. 网络编程(网络通信)
  2. 通过浏览器访问服务器

知识点

网络编程(网络通信)

服务器:是一台电脑,低配版
客户端:是一台电脑,是手机,是平板,是网页

我们可以自己的电脑上搭建服务器环境,模拟客户端和服务器之间的网络通信

Socket编程

Socket编程是建立在TPC/IP协议上的

同一网络环境下,如何访问其他主机?

通过 IP地址 加 端口号 的形式访问其他主机

怎么查看自己的IP地址

通过CMD,ipconfig查看ipv4地址,是当前局域网下的ip地址

特点

一台电脑可以有多个端口号,每个端口号对应的程序也可以不同
当我们用ip地址+端口号访问一个指定程序的时候,端口号不同,程序不同

Socket通信

接下来就要在自己的电脑开辟一个端口号,这个端口号就是服务器的端口

简单的服务器读取客户端信息

 @Test
    public void server() throws IOException {
        //创建了一个服务器对象,绑定在8888端口
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务器已经启动");
        //服务器在等待客户端连接
        Socket socket = serverSocket.accept();
        //读取客户端发来的信息,读流
        InputStream inputStream = socket.getInputStream();
        byte [] buffer = new byte[1024*1024];
        int len;
        while ((len = inputStream.read(buffer)) != -1){
            System.out.println("服务器已经接受了客户端的数据" + new String(buffer,0,len));
        }
        //释放资源
        inputStream.close();
        socket.close();
    }


    @Test
    public void client() throws IOException {
        //创建了一个Socket通信的客户端
        Socket socket = new Socket();
        //第一个参数就是获取当前电脑的IP地址
        //第二个参数就是服务器的端口号
        socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(),8888));
        //客户端发送数据给服务器
        OutputStream outputStream = socket.getOutputStream();
        String data = "hello server!";
        outputStream.write(data.getBytes());
        System.out.println("客户端已经发送数据" + data);
        outputStream.close();
        socket.close();
    }

服务器接收客户端信息,再返回信息给客户端,客户端接收信息

    @Test
    public void server() throws IOException {
        // 创建了一个服务器对象,绑定在8888端口
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务器已启动...");
        // 服务器在等待客户端连接
        Socket socket = serverSocket.accept();
        // 读取客户端发送过来的信息
        InputStream inputStream = socket.getInputStream();
//        InputStream inputStream1 = new FileInputStream("");
        OutputStream outputStream = new FileOutputStream("d:/Pointofix.exe");
        // 我们要再获取一个输出流,这个输出流是为了给客户端返回数据
        OutputStream clientOutputStream = socket.getOutputStream();

        byte [] buffer = new byte[1024 * 1024];
        int len;
        while((len = inputStream.read(buffer)) != -1){
            // 接收信息,接的是什么信息?
            // 看输入流是怎么来的?
            // 我们现在的输入流是怎么来的?
            // 通过socket获取到的
            // socket是怎么来的?
            // socket是通过服务器启动之后,接到的客户端连接
            // 我们的输入流就是客户端的输入流
            // 因为我们现在接收的是一个文件
            // 我们需要把这个文件另存
            // 我们需要构建一个输出流,把这个文件保存在硬盘上
            outputStream.write(buffer,0,len);
        }
        System.out.println("文件接收成功...");
        // 给客户端返回一个数据
        clientOutputStream.write("文件已成功保存到服务器...".getBytes());
        // 释放资源
        inputStream.close();
        outputStream.close();
        socket.close();
    }

    @Test
    public void client() throws IOException {
        // 创建了一个Socket通信的客户端
        Socket socket = new Socket();
        // 第一个参数就是获取当前电脑的IP地址
        // 第二个参数就是服务器的端口号
        socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(),8888));
        // 客户端发送数据给服务器
        OutputStream outputStream = socket.getOutputStream();
        File file = new File("e:/Pointofix.exe");
        InputStream inputStream = new FileInputStream(file);
        // 我们现在要读取的是服务器的数据,就需要构建一个从服务器来的输入流
        InputStream serverInputStream = socket.getInputStream();
        // 要发送的文件
        byte [] buf = new byte[1024 * 1024];
        int len;
        while((len = inputStream.read(buf)) != -1){
            // 把读取到的文件循环发送给服务器
            // 输出流把文件写出去,写到哪里去了?
            // 输出流,首先要看这个输出流是怎么来的,就能够确定这个内容要输出到哪里?
            // 我们现在的输出流是通过socket获取到的
            // 所以说我们现在的写的操作就是把文件写给服务端
            outputStream.write(buf,0,len);
        }
        System.out.println("文件发送成功...");

        // 要通知服务器文件已发送完毕,下面的操作是等待服务器的回复
        // 通知服务器数据已经发送完毕
        /* 如果没有这行代码会进入死循环,下面的代码也是一个读的代码,
           服务器会认为客户端传输信息没有传完,而实际上下面读的代码是
           用来接收服务器返回的信息的,会一直等服务器的返回信息,这样
           两边就都在等。。。
         */
        socket.shutdownOutput();

        // 接收服务器回传的数据
        byte [] serverBuf = new byte[1024 * 1024];
        int serverLen;
        while((serverLen = serverInputStream.read(serverBuf)) != -1){
            System.out.println(new String(serverBuf,0,serverLen));
        }
        inputStream.close();
        outputStream.close();
        socket.close();
    }

UDP:不可靠的传输协议

效率非常长高,但容易丢数据的传输手段,只是快,后果严重

 @Test
    public void client() throws IOException {
        DatagramSocket Socket = new DatagramSocket();
        String str = "我通过UDP协议发的消息。。。";
        byte [] data = str.getBytes();
        //构建成了一个数据范文
        //第一个参数就是要发送的数据
        //第二个参数就是要从哪法
        //第三个参数就是发多长
        //第四个参数就是指定服务器的ip地址
        //第五个参数就是服务器的端口号
        DatagramPacket packet = new DatagramPacket(data,0,data.length, InetAddress.getLoopbackAddress(),9999);
        //发送数据
        Socket.send(packet);
        System.out.println("数据发送成功!!!");
        Socket.close();
    }
    @Test
    public void server() throws IOException {
        //服务器指定端口
        DatagramSocket socket = new DatagramSocket(9999);
        byte [] buffer = new byte[1024*1024];
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
        socket.receive(packet);
        System.out.println(new String(packet.getData(),0,packet.getLength()));
        socket.close();
    }

面试题

TCP/IP协议和UDP的区别?

TCP/IP:客户端和服务器要有稳定连接(三次握手,四次挥手)、要用到输入输出流接收和传送信息,
        服务器不开,直接开客户端会报错
UDP:不需要连接,不需要IO流,直接根据服务器地址、端口号发送信息
     只单纯的发送/接收信息,有没有信息都在发送/接收

URL工具类

格式: 协议 主机名 端口号 资源地址

一个URL对应着互联网的一个资源网址
URL:https://www.163.com/
URL:https://192.168.1.1:8888/goods

  public static void main(String[] args) {
        try {
            URL url = new URL("https://192.168.1.1:8888/demo/list.html?usenrame=123&password=123456");
            //获取协议
            System.out.println(url.getProtocol());
            //获取主机地址
            System.out.println(url.getHost());
            //获取端口号
            System.out.println(url.getPort());
            //地址
            System.out.println(url.getPath());
            //拿到文件---就是端口号后面所有的信息
            System.out.println(url.getFile());
            //查询参数---?后面的内容
            System.out.println(url.getQuery());
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }

InetAddress工具类

 public static void main(String[] args) {
        try {
            InetAddress inet1 = InetAddress.getByName("192.168.1.1");
            System.out.println(inet1);
            InetAddress inet2 = InetAddress.getByName("www.baidu.com");
            System.out.println(inet2);
            // 获取本地ip
            InetAddress localHost = InetAddress.getLocalHost();
            System.out.println(localHost);
            // 获取本机的主机名
            System.out.println(localHost.getHostName());
            System.out.println(localHost.getHostAddress());
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }

软件架构

  1.   C/S架构:Client/Server客户端/服务器,QQ,360,腾讯会议,游戏
  2.   B/S架构:Browser/Server浏览器/服务器,

  移动互联,手机端为主,C/S架构,

Java两种架构都可以做,主要要做的就是架构中的Server端。

1.静态资源:所有用户访问后,得到的结果都是一样的。html
2.动态资源:每个用户访问后,得到的结果可能不一样。爱奇艺,

web服务器

格式:接收用户的请求,处理请求,给出响应。

通过浏览器访问我们的ServerSocket服务器,我们用浏览器通过IP地址 + 端口号
给ServerSocket服务器发起了请求:我要访问服务器!!!

(请求)

public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8080);
        // 等待客户端的连接
        Socket accept = serverSocket.accept();
        // 获取一个输入流来读取客户端发送的数据
        InputStream inputStream = accept.getInputStream();
        byte [] buf = new byte[1024];
        int len;
        while((len = inputStream.read(buf)) != -1){
            System.out.println(new String(buf,0,len));
        }

        inputStream.close();
        accept.close();
    }

端口号自己定义,怎么获得IP地址?

本机的IP地址:
1.cmd---ipconfig
2.127.0.0.1---本机(个人建议,任何情况都好使)
3.localhost---本机(前提条件:你的电脑要联网,激活一下网卡)

运行以上代码发现,我们什么信息也没发送,但是我们通过浏览器访问我们的ServerSocket,得到了一堆信息, 通过一些信息:

  • User-Agent:告诉服务器我是从什么样的客户端来的。

  • Host: 127.0.0.1:8080,主机地址,目标主机。

可以推断:貌似浏览器也是通过Socket和我们的服务器建立了TCP连接

其实发送过来的信息叫报文,是浏览器传递过来的一些消息。

我们称之为“请求”,而且这个请求格式满足了http的协议。

而服务器收到请求后回给浏览器做出响应,需要遵循浏览器的格式要求:

一次请求和响应称为会话:

请求:客户端--->服务器

响应:服务器--->客户端

(响应)

  public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务器启动成功...");
        Socket server = serverSocket.accept();
        OutputStream outputStream = server.getOutputStream();
        // 按照http协议的格式封装一个报文数据
        String response = "HTTP/1.1 200 OK\r\n"+
                "Content-Length: 39\r\n" +
                "Content-Type: text/html;charset=UTF-8\r\n\r\n" +
                "<h1>hello server</h1>";
        outputStream.write(response.getBytes());
        outputStream.flush();
        // 这个流不要着急关,因为突然的关闭会导致浏览器和服务器断开连接
    }

重定向

假如我要访问的是www.baidu.com,结果页面展示的是www.jd.com

重定向会重新定位到新的页面,而且地址栏的地址也会随之变化。

public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务器启动成功...");
        Socket server = serverSocket.accept();
        OutputStream outputStream = server.getOutputStream();
        // 按照http协议的格式封装一个报文数据
        String response = "HTTP/1.1 302 Moved Temporarily\r\n"+
                "Location: https://www.baidu.com\r\n\r\n";
        outputStream.write(response.getBytes());
        outputStream.flush();
        // 这个流不要着急关,因为突然的关闭会导致浏览器和服务器断开连接
    }


网站公告

今日签到

点亮在社区的每一天
去签到