复习6(网络编程)

一、网络通信的基本模式

1.CS模式(Client---客户端,Server---服务端)

客户端是需要程序员去开发的,例如日常使用的各种的APP,服务端就是服务器。

例子:QQ,端游,依赖特定的PC端才能玩。

2.BS模式(Browser---浏览器,Server---服务端)---重点学习

服务端是需要程序员去开发的。浏览器就是我们日常使用的浏览器去访问各种网站,只要有浏览器就可以访问,不依赖特定的PC端,在任意设备上都可以访问网站服务器 。

例子:网页小游戏,联网浏览器就可以玩。 

3.C/S和B/S架构相比的各自的优缺点

CS(客户端--服务器结构)

优点 :技术成熟,交互性强,网络通信量低,响应数据快。将任务分到了两端,降低了系统的开销。客户端要处理大多数的业务逻辑和UI展示。他是胖客户端。

缺点:更新太快,要求用户有相同的操作系统,如果有不同的操作系统还要开发不同的版本,对于计算机电脑的配置要求也高

BS(浏览器-服务器结构)

优点:主要事务在服务端实现。分布性强、维护方便、开发简单、共享性强、总体成本低,对客户端的电脑配置要求较低

缺点:数据安全性问题,对服务器要求高。数据传输速度较慢,软件的个性化明显降低,难以实现传统模式下的特殊功能要求,他是瘦客户端,大量的数据的传输都要通过服务器与浏览器进行交互,通信开销大,难以实现复杂的应用构造

二、实现网络编程的三种要素

IP地址可以理解为具体哪个计算机,端口理解计算机上的程序(一个程序一个端口),协议理解为电脑通过什么方式和外界交互

要素一:IP地址:设备在网络中的地址,是唯一的标识

(1)常见的IP分类为:

IPv4(32比特4字节)和IPv6(128位16个字节)--称号--可以标记地球上的每一粒沙子。

(2)IP地址的取经之路:

计算机:我要去找百度获取数据。

DNS服务器:发过来我看看哪个网址域名啊,给你指路具体的ip地址

计算机:知道了这个ip地址,我就可以去找具体要访问的服务器了

服务器:计算机老弟你来找我了啊,那我把你要的数据发给你吧。 

(3)公网地址和私有地址(局域网使用)

192.168开头的就是常见的私有地址 

(4)获取IP地址的代码

 要去实现这个IP地址的获取就要用到 InetAddress方法

public static void main(String[] args) throws Exception {
        //获取本机地址ip对象
        InetAddress localHost = InetAddress.getLocalHost();
        //获取本机名字
        System.out.println(localHost.getHostName());
        //获取本机ip地址
        System.out.println(localHost.getHostAddress());
        //获取百度(域名)ip对象
        InetAddress baidu = InetAddress.getByName("www.baidu.com");
        System.out.println(baidu.getHostName());
        System.out.println(baidu.getHostAddress());
        //获取公网对象
        InetAddress byName = InetAddress.getByName("112.80.248.76");
        System.out.println(byName.getHostName());
        System.out.println(byName.getHostAddress());
        //判断链接5s前是否成功
        System.out.println(byName.isReachable(5000));
    }

要素二:端口:应用程序在设备中的唯一标识

一个主机设备中,端口号是唯一的

(1)端口号:一个程序一个端口号,被规定为16位的二进制,范围是0~65535

(2)周知端口:0~1023,被预先定义的知名应用占用。(例如:HTTP占用80端口,FTP占用21端口)

(3)注册端口:1024~49151,分配给用户进程或某些程序(例如:Tomcat占用8080端口)

(4)动态端口:49152~65535,不固定分配到某种进程,动态分配

要素三:协议:数据在网络中的传输协议,最常见的有UDP和TCP(重点)

TCP/IP 参考模型 各层对应 面向操作
应用层 HTTP、FTP、DNS、SMTP... 应用程序一般在这一层开发
传输层 TCP、UDP...  选择使用的TCP、UDP...
网络层 IP、ICMP... 封装源头和目标IP,进行路径选择
数据链路和物理层 物理寻址、比特流... 物理设备中传输

图解OSI七层结构模型 - 知乎 (zhihu.com)

(1)TCP协议: (安全,有连接确认可靠)

使用TCP协议,双方必须先建立连接,它是一种面向连接的可靠通信协议,传输前,要建立三次握手方式建立连接确认。连接和发送数据都需要确认。传输完成后,还需要释放已连接的通信,通信效率相对比较低。

使用场景:对安全需求较高的文件下载、金融数据通信等。

(90条消息) 图文并茂,讲解TCP和UDP协议的原理以及区别_tcp协议图像udp 图像传输比较_肥肥技术宅的博客-CSDN博客

服务端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
 
//服务端
public class Test1 {
    public static void main(String[] args) throws IOException {
        System.out.println("========服务端启动============");
        //1.创建接收管道,注册端口
        ServerSocket serverSocket = new ServerSocket(7777);//参数一:定义服务端口
        //2.等待管道连接
        Socket accept = serverSocket.accept();
        //3.从管道中获取一个字节输入流
        InputStream is = accept.getInputStream();
        //4.字节流升级生缓冲输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        //5.按照行读取消息会更好
        String a;
        if ((a = br.readLine())!=null){
            System.out.println(accept.getRemoteSocketAddress()+"说了:"+a);
        }
    }
}

客户端:

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
 
//发送端
public class Test {
    public static void main(String[] args) throws IOException {
        System.out.println("==============客户端启动===============");
        //1.创建发送通信管道
        Socket socket = new Socket("127.0.0.1",7777);//参数一:服务端地址 参数二:服务端端口
        //2.从scoket管道中获得一个字节输出流,负责发送数据
        OutputStream os = socket.getOutputStream();
        //3.字节流升级成打印流
        PrintStream ps = new PrintStream(os);
        //4.发送消息
        ps.println("大哥,我来了");
        ps.flush();//刷新
    }
}

(2)UDP协议:(速度快,无连接,不可靠)

不需要建立连接(因为把数据源IP、目的地IP、端口封装成数据包),每个数据包在64KB内,只管发,不管对方有没有接到确认什么的。

优点:可以广播发送,发送数据结束时无需释放资源,开销小,速度快。

使用场景:语言通话、视频通话等。

ps:这个就是一股脑的什么都封装一起,直接往外抛就什么都不管了,当然快了

发送端:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
 
public class Test1 {
    public static void main(String[] args) throws Exception {
        //二、接收端(测试时候先启动接收再发送端)
        //1.创建接收端对象,注册端口(人)
        System.out.println("=========接收端启动===============");
        DatagramSocket socket2 = new DatagramSocket(8899);
 
        //2.创建一个要接收的数据容器(等待接收数据)
        byte[]b =new byte[1024*64];
        //3.把容器数据打包
        DatagramPacket packet2 = new DatagramPacket(b,b.length);
        //4.等待接收数据
        socket2.receive(packet2);
        //5.读取多少倒出多少
        int len = packet2.getLength();
        String rs = new String(b,0,len);
        System.out.println("接收到了数据了"+rs);
 
        //6.关闭资源,避免资源浪费
        socket2.close();
    }
}

接收端:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
//二、接收端
public class Test1 {
    public static void main(String[] args) throws Exception {
        //1.创建接收端对象,注册端口(人)
        System.out.println("=========接收端启动===============");
        DatagramSocket socket2 = new DatagramSocket(8899);
 
        //2.创建一个要接收的数据容器(等待接收数据)
        byte[]b =new byte[1024*64];
        //3.把容器数据打包
        DatagramPacket packet2 = new DatagramPacket(b,b.length);
        while (true) {//二、6.把封装代码写入死循环并删掉释放资源的代码(多收多发步骤)
            //4.等待接收数据
            socket2.receive(packet2);
            //5.读取多少倒出多少
            int len = packet2.getLength();
            String rs = new String(b,0,len);
            System.out.println("接收到了来自:"+packet2.getAddress()+"对方端口是:"+packet2.getPort()+rs);
        }
    }
}

 

posted @ 2023-07-15 17:38  K1_KCY  阅读(3)  评论(0)    收藏  举报