计算机网络1

1 协议

“协议” 就是一个规范/约定。

1.1 网络协议分类

网络协议有两大分类方法:

  1. OSI 七层模型(这每层模型是啥,代表的什么含义必须背过)
  2. TCP/IP协议(四层),它也是http协议的一个基础,也就是http协议是依靠TCP/IP协议实现的。http是应用层协议。

1.1.1 OSI 七层网络模型

  1. 应用层
    应用层存放的就是程序,我们编写的程序就放在应用层里面。
    功能:针对特定应用的协议。
    比如:电子邮件通过电子邮件协议、远程登录通过远程登录协议、文件传输通过文件传输协议进行链接等。
    应用层里面著名的协议有HTTP、SSH、FTP。
  2. 表示层
    将网络信息包转换成程序需要的数据结构。
    功能:设备固有数据格式和网络标准数据格式的转换。
  3. 会话层
    管理断开和连接会话的。
    功能:通信管理。负责建立和断开通信连接,管理传输层以下的分层。
  4. 传输层
    填写收件人信息和发件人信息的,也就是管理目标地址和原地址的ip和端口号的。
    功能:管理两个节点之间的数据传输,负责可靠传输(确保数据被可靠地传送到目标地址)。
    网络交互必备的5个部分:目标地址IP、目标地址的端口、源地址IP、源端口号和协议。
    传输层里面著名的协议有TCP、UDP,两者的区别是:
    (1) UDP:无连接、不可靠、面向字节报的。
    (2) TCP:需要连接、可靠、面向字节流的。
  5. 网络层
    选择快递传输的方式(用车还是用飞机)
    功能:地址管理和路由选择。
    网络层里面著名的协议有IP。
  6. 数据链路层
    确定具体的传输路径。
    功能:互联设备之间传送和识别数据帧。
  7. 物理层
    用来发光信号和电信号的。
    功能:以0、1代表电压的高低、灯光的闪灭。界定连接器和网线的规格。

1.1.2 TCP/IP协议(四层或五层)

  1. 应用层
  2. 传输层
  3. 网络层
  4. 数据链路层
  5. 物理层(可忽略,忽略掉就为4层了)

2 封装/分用

封装就是数据一层一层往下传递的过程。
分用就是封装相反的过程。
在这里插入图片描述

3 IP

IP是指互联网地址标识,我们所说的IP通常是指IPv4和IPv6,但由于IPv6还没有普及,所以泛指的还是IPv4。
IPv4是由32位组成,分为四部分,十进制" . " 分发法,数据范围是0-255。

4 Mac

Mac地址是物理地址,也叫网卡地址。
规则:它在机器出厂时就已经制定好了,那么原则上来说它是全球唯一的。也就是出厂之后会随机分配一个全球唯一的地址。
如果是Linux系统,那么格式是 xx:xx:xx…;如果是Windows系统,那么格式是xx-xx-xx-xx…。
在这里插入图片描述

5 网络编程(TCP/UDP开发)

传输层协议:TCP、UDP。

  1. 下面将使用UDP进行编程示例,实现一个客户端和服务器端的UDP交互。
    需要创建两个类,一个是客户端,一个是服务器端。
    客户端类:
package UDP;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

/*
 * UDP客户端
 * */
public class UDPClient {
    //服务器端IP
    private static final String ip = "127.0.0.1";
    //服务器端端口号
    private static final int port = 9001;
    //数据包大小
    private static final int bleng = 1024;

    public static void main(String[] args) throws IOException {
        //1.创建客户端
        DatagramSocket socket = new DatagramSocket();

        //让用户来输入发送的消息
        Scanner scanner = new Scanner(System.in);
        while(true){
            System.out.println("->");
            //接收到用户输入的信息
            String msg = scanner.nextLine();
            //2.构建发送数据包
            DatagramPacket datagramPacket = new DatagramPacket(
                    msg.getBytes(),
                    msg.getBytes().length,
                    InetAddress.getByName(ip),
                    port
            );
            //3.发送消息
            socket.send(datagramPacket);
            DatagramPacket serPacket = new DatagramPacket(new byte[bleng],bleng);
            //接收服务器端的消息
            socket.receive(serPacket);
            System.out.println("收到服务器端的信息"+new String(serPacket.getData()));
        }
    }
}

服务器端类:

package UDP;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/*
* UDP服务器
* */
public class UDPServer {
    //端口号
    private static final int port = 9001;
    //接收数据容器的大小
    private static final int bleng = 1024;

    public static void main(String[] args) throws IOException {
        //1.创建一个udp服务器
        DatagramSocket socket = new DatagramSocket(port);
        while(true){
            DatagramPacket clientPacket = new DatagramPacket(new byte[bleng],bleng);
            //2.等待客户端连接
            socket.receive(clientPacket);
            //执行此代码表示已经有客户端连接了
            //3.拿到客户端的请求信息
            String msg = new String(clientPacket.getData());
            System.out.println("接收到客户端的消息:"+msg);
            //4.补充功能:给客户端反馈一个消息
            String serMsg = "我收到了";
            //String serMsg = msg.replace("吗?",".").repalce("你","我");
            //构建客户端发送数据包
            DatagramPacket serPacket = new DatagramPacket(
                    serMsg.getBytes(),
                    serMsg.getBytes().length, //注意是字节数组的长度
                    clientPacket.getAddress(),
                    clientPacket.getPort()
            );
            //给客户端发送消息
            socket.send(serPacket);
        }
    }
}

一般先启动服务器端,再启动客户端。
如何把普通的项目部署到服务器上,然后通过本地这个客户端来连接服务器上的应用呢?
在这里插入图片描述

  1. 下面将使用TCP进行编程示例,实现一个客户端和服务器端的TCP交互。
    也需要创建两个类,一个是客户端,一个是服务器端。
    客户端类:
package TCP;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/*
 * TCP客户端
 * */
public class TCPClient {
    //服务器端IP
    //服务器端IP
    private static final String ip = "127.0.0.1";
    //服务器端端口号
    private static final int port = 9002;
    public static void main(String[] args) throws IOException {
        //1.创建tcp客户端,并且链接服务器端
        Socket socket = new Socket(ip,port);

        try(BufferedReader reader = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream())
            );Scanner scanner = new Scanner(System.in);
            ){
            while(true){
                System.out.println("->");
                String msg = scanner.nextLine();
                //2.发送消息给服务器端
                writer.write(msg + "\n");
                writer.flush();
                //3.接收服务器响应的内容
                String serMsg = reader.readLine();
                System.out.println("服务器反馈:" + serMsg);
            }
        }

    }
}

服务器端类:

package TCP;

import com.sun.scenario.effect.impl.sw.java.JSWBlend_SRC_OUTPeer;
import sun.java2d.pipe.BufferedTextPipe;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/*
 * TCP服务器
 * */
public class TCPServer {
    //端口号
    private static final int port = 9002;
    public static void main(String[] args) throws IOException {
        //1.创建TCP服务器端
        ServerSocket serverSocket = new ServerSocket();
        System.out.println("服务器启动成功!");

        //2.等待客户端得连接
        Socket client = serverSocket.accept();
        System.out.println(String.format("有客户端连接了,客户端IP:%s,端口:%d",client.getInetAddress().getHostAddress(),client.getPort()));

        //try-catch
//        BufferedReader bufferedReader = null;
//        BufferedWriter bufferedWriter = null;
//        try {
//            //拿到读取对象
//             bufferedReader = new BufferedReader(
//                    new InputStreamReader(client.getInputStream())
//            );
//            //接收服务器端的信息
//            String msg = bufferedReader.readLine();
//            //拿到写入对象
//            bufferedWriter = new BufferedWriter(
//                    new OutputStreamWriter(client.getOutputStream())
//            );
//            String serMsg = "我收到了";
//            bufferedWriter.write(serMsg + "\n"); //写入消息必须加 \n ,因为它在读取的时候是按行进行读取的,如果不加这个换行符,你是读取不到的,所以写入不成功。即因为客户端需要按行读取信息,所以在写入时必须加上换行符,作为最后的后缀信息。
//            //刷新缓冲区
//            bufferedWriter.flush();
//        }finally {
//            if(bufferedReader != null){
//               bufferedReader.close();
//        }
//            if(bufferedWriter != null){
//                bufferedWriter.close();
//            }
//        }

        //try-resouce
        try(BufferedWriter bufferedWriter = new BufferedWriter(
                new OutputStreamWriter(client.getOutputStream())
        );BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(client.getInputStream())
        )
        ){
            while(true){
                //3.接收客户端的消息
                String msg = bufferedReader.readLine();
                if(msg != null && msg.equals("")){
                    System.out.println("收到客户端信息" + msg);
                    //4.返回给客户端响应信息
                    String serMsg = "我收到了";
                    bufferedWriter.write(serMsg + "\n");
                    //缓冲区刷新
                    bufferedWriter.flush();
            }}
        }
    }
}

TCP为了加速发送和接收,它创建了一个缓冲区,也就是缓存区,严格意义上来讲是创建了两个缓冲区,为:发送缓冲区和接收缓冲区(提高性能的措施)。

  1. 使用TCP实现一个英译汉操作,也就是客户端输入为英文,服务器端解析为中文。
    客户端类:
package TCP;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/*
 * 英译汉客户端
 * */
public class CNTCPClient {
    //服务器端IP
    //服务器端IP
    private static final String ip = "127.0.0.1";
    //服务器端端口号
    private static final int port = 9003;
    public static void main(String[] args) throws IOException {
        //1.创建tcp客户端,并且链接服务器端
        Socket socket = new Socket(ip,port);

        try(BufferedReader reader = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream())
            );Scanner scanner = new Scanner(System.in);
        ){
            while(true){
                System.out.println("英文:");
                String msg = scanner.nextLine();
                //2.发送消息给服务器端
                writer.write(msg + "\n");
                writer.flush();
                //3.接收服务器响应的内容
                String serMsg = reader.readLine();
                System.out.println("中文:" + serMsg);
            }
        }

    }
}

服务器端:

package TCP;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;

/*
* 英译汉服务器
* */
public class CNTCPSrever {
    //端口号
    private static final int port = 9003;
    //定义翻译字典
    static HashMap<String,String> dirMap = new HashMap<>();
    static {
        dirMap.put("hello","你好");
        dirMap.put("cat","猫");
        dirMap.put("dog","狗");
    }
    
    
    
    public static void main(String[] args) throws IOException {
       //1.创建TCP服务器端
        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("英译汉服务器启动成功!");

        //2.等待客户端得连接
        Socket client = serverSocket.accept();
        //执行到此行说明已经有客户端连接
        System.out.println(String.format("有客户端连接了,客户端IP:%s,端口:%d",client.getInetAddress().getHostAddress(),client.getPort()));

        //try-resouce
        try(BufferedWriter bufferedWriter = new BufferedWriter(
                new OutputStreamWriter(client.getOutputStream())
        ); BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(client.getInputStream())
        )
        ){
            while(true){
                //3.得到客户端的英文单词
                String en = bufferedReader.readLine();
                if(en != null && !en.equals("")){
                //4.英译汉结果的处理方法
                String cn = processData(en);
                //5.将结果返回给客户端
                bufferedWriter.write(cn + "\n");
                //缓冲区刷新
                bufferedWriter.flush(); }}
        }
    }
    //英译汉方式1
    private static String processData(String en){
        String cn = "未知";
        switch (en){
            case "hello":
                cn = "你好";
                break;
            case "cat":
                cn = "猫";
                break;
            case "dog":
                cn = "狗";
                break;
                //......
            default:
                break;
        }
        return cn;
    }
    
    //英译汉方式2
    private static String processData2(String en){
        //可以调用数据库查询英文的结果
        String cn = "未知";
        cn = dirMap.get(en);
        return cn;
        
    }
}
  1. 因为HTTP协议是基于TCP/IP实现的,所以我们学会了TCP开发也就能开发一个简单的http服务器了。我们只需要TCP遵循http协议的一个规范就可以开发出简易版Http服务器:根据不同的URL地址,返回不同的信息。
    xxx/404 -> 没有找到页面
    xxx/200 -> 你好,世界
package TCP;
/*
简易版HTTP
 */

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServerByHTTP {
    //端口号
    private static final int port = 9004;
    public static void main(String[] args) throws IOException {
        //1.创建TCP服务器端
        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("服务器启动成功!");

        //2.等待客户端的连接
        Socket client = serverSocket.accept();
        //执行到此行说明已经有客户端连接
        System.out.println(String.format("有客户端连接了,客户端IP:%s,端口:%d",client.getInetAddress().getHostAddress(),client.getPort()));

        //3.得到两个读写对象
        try(BufferedWriter bufferedWriter = new BufferedWriter(
                new OutputStreamWriter(client.getOutputStream())
        ); BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(client.getInputStream())
        )
        ){
                //读取首行信息 【方法类型】【url】【http版本号】
                String en = bufferedReader.readLine();
                if(en != null && !en.equals("")){
                    String[] fLine = en.split("");
                    //读取到请求方法的类型
                    String method = fLine[0];
                    //读取到url
                    String url = fLine[1];
                    //读取http版本号
                    String httpVer = fLine[2];
                    System.out.println(String.format("读取到了客户端请求,方法类型:%s,URL:%s,版本:%s",method,url,httpVer));
                    //4.业务逻辑处理
                    String content = "<h1>未知</h1>";
                    if(url.contains("404")){
                        content = "<h1>没有找到此页面</h1>";
                    }else if(url.contains("200")){
                        content = "<h1>你好,世界!</h1>";
                    }
                    //5.将结果打印到浏览器上
                    //写入首行信息
                    bufferedWriter.write(httpVer + "200 ok\n ");
                    //写入Head(Content-Type/Content-Length)
                    bufferedWriter.write("Content-Type:text/html;charset=utf-8;\n");
                    bufferedWriter.write("Content-Length: "+ content.getBytes().length+"\n");
                    //写入空行
                    bufferedWriter.write("");
                    //写入body
                    bufferedWriter.write(content);
                    //缓冲区刷新
                    bufferedWriter.flush(); }}
        }
}

6 总结

jar包和war包的区别:

  1. jar包是普通Java项目包的格式,它在所有jdk中都可以通过:java -jar jar名字来启动。
  2. war包是web程序的应用包,它必须放在web容器中才能启动,例如Tomcat、Nginx。
  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值