计算机网络编程

网络编程

文章目录

  • 网络编程
    • 1 计算机网络
      • 1.1 什么是网络
      • 1.2 什么是计算机网络
      • 1.3 计算机网络发展的四个阶段
    • 2 常用名词
      • 2.1 网络模型
        • 2.1.1 OSI模型
        • 2.1.2 TCP/IP模型
      • 2.2 网络协议
        • 2.2.1 TCP/UDP
        • 2.2.2 IP
      • 2.3 Port: 端口号
    • 3 计算机网络编程
      • 3.1 InetAddress类
      • 3.2 基于TCP的Socket网络编程
      • 3.3 基于UDP协议的Socket编程

1 计算机网络

1.1 什么是网络

概念:由点和线构成,表示诸多对象间的相互联系。

计算机网络编程_第1张图片

1.2 什么是计算机网络

概念:计算机网络是将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路和通信设备连接起来的一种计算机系统。

计算机网络编程_第2张图片

作用:在网络操作系统、网络管理软件及网络通信协议的协同管理下,可以实现资源的共享和信息的高效传递。

常见的计算机网络

  • 互联网:(Internet)点与点相连
  • 万维网:(WWW – World Wide Web)端与端相连
  • 物联网:( IoT - Internet of things) 物与物相连

网络编程:让计算机与计算机之间建立连接、进行通信。

根据地理范围分类:局域网:一个学校、公司、机房。城域网:一个或多个城市。广域网:Internet

1.3 计算机网络发展的四个阶段

第一阶段(60年代初期到60年代中期)

计算机通信网络,特征是计算机与终端互联,实现远程访问。第一代计算机网络是有主机—通信线路—终端组成,只可算是计算机网络的雏形。

(1)具有远程通信功能的单机系统

Ø解决了多个用户共享主机资源的问题。终端为哑终端,没有自己的CPU、内存和硬盘,没有处能力。

Ø存在问题:主机负担重,通信费用高。

计算机网络编程_第3张图片

(2)具有远程通信功能的多机系统

Ø解决了主机负担重、通信费用昂贵的问题。

Ø存在问题:多个用户只能共享一台主机资源。

计算机网络编程_第4张图片

第二阶段(60年代中期到70年代中期):

采用分组交换技术实现计算机 — 计算机之间的通信,使计算机网络的结构、概念都发生了变化,形成了通信子网和资源子网的网络结构。

(1)第二代计算机网络是计算机网络的“形成与发展”阶段

(2)美国的ARPA网就是第二代网络的代表

主要问题:网络对用户不是透明的。

第三阶段(70年代中期到80年代末期):

现代计算机网络互连阶段,特征是网络体系结构的形成和网络协议的标准化。

在计算机通信系统的基础之上,重视网络体系结构和协议标准化的研究,建立全网统一的通信规则,用通信协议软件来实现网络内部及网络与网络之间的通信,通过网络操作系统,对网络资源进行管理,极大的简化了用户的使用,使计算机网络对用户提供透明服务 。

(1)局域网技术出现突破性进展。

Ø该阶段始于70年代末,这是按照ISO提出的OSI参考模型为指导性标准构建的计算机网络。

Ø第三代计算机网络是计算机网络的“成熟”阶段。

(2)第三代计算机网络的特点

Ø 网络体系结构的形成和网络协议的标准化

Ø 建立全网统一的通信规则

Ø 使计算机网络对用户提供透明服务

第四阶段 –高速、综合化网络:

该阶段始于80年代末,相继出现了快速以太网、光纤分布式数字接口(FDDI)、快速分组交换技术(包括帧中继、ATM)、千兆以太网、B-ISDN 等一系列新型网络技术,这就是高速与综合化计算机网络阶段。

Internet就是这一代网络的典型代表,已经成为人类最重要的、最大的知识宝库。第四代计算机网络属于计算机网络的“继续发展”阶段。

把计算机网络的发展分为4个阶段:

Ø第一代:面向终端的计算机网络

Ø第二代:计算机通信网络

Ø第三代:计算机互联网络

Ø第四代:宽带综合业务数字网(信息高速公路)

2 常用名词

2.1 网络模型

2.1.1 OSI模型

OSI(Open System Interconnection)开放式系统互联。

计算机网络编程_第5张图片

  • 应用层:应用层负责文件访问和管理、可靠运输服务、远程操作服务。(HTTP、FTP、SMTP)
  • 表示层:表示层负责定义转换数据格式及加密,允许选择以二进制或ASCII格式传输。
  • 会话层:会话层负责使应用建立和维持会话,使通信在失效时继续恢复通信。(断点续传)
  • 传输层:传输层负责是否选择差错恢复协议、数据流重用、错误顺序重排。(TCP、UDP)
  • 网络层:网络层负责定义了能够标识所有网络节点的逻辑地址。(IP地址)
  • 数据链路层:链路层在物理层上,通过规程或协议(差错控制)来控制传输数据的正确性。(MAC)
  • 物理层:物理层为设备之间的数据通信提供传输信号和物理介质。(双绞线、光导纤维)
2.1.2 TCP/IP模型

TCP/IP模型:一组用于实现网络互连的通信协议,将协议分成四个层次。

计算机网络编程_第6张图片

  • 应用层:负责传送各种最终形态的数据,是直接与用户打交道的层,典型协议是HTTP、FTP等。
  • 传输层:负责传送文本数据,主要协议是TCP、UDP协议。
  • 网络层:负责分配地址和传送二进制数据,主要协议是IP协议。
  • 接口层:负责建立电路连接,是整个网络的物理基础,典型的协议包括以太网、ADSL等等。

2.2 网络协议

2.2.1 TCP/UDP

通信协议:计算机之间通信的规范标准。

TCP协议:Transmission Control Protocol 传输控制协议

  • 是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。
  • 建立连接的过程需要三次握手,断开连接的过程需要四次挥手。

计算机网络编程_第7张图片

UDP协议:User Datagram Protocol 用户数据报协议

  • 是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB。
  • 效率比TCP高,适合广播发送。
2.2.2 IP

IP协议:Internet Protocol 互联网协议/网际协议

  • 分配给互联网设备的数字标签(唯一标识)称为IP地址。

IP地址分为两种

IPV4:4字节32位整数,并分成4段8位的二进制数,每8位之间用圆点隔开,每8位整数可以转换为一个0~255的十进制整数。

IPV6:16字节128位整数,并分成8段十六进制数,每16位之间用圆点隔开,每16位整数可以转换为一个0~65535的十进制数。

IPV4的应用分类

  • A类:政府机构,1.0.0.1 ~ 126.255.255.254
  • B类:中型企业,128.0.0.1 ~ 191.255.255.254
  • C类:个人用户,192.0.0.1 ~ 223.255.255.254
  • D类:用于组播,224.0.0.1 ~ 239.255.255.254
  • E类:用于实验,240.0.0.1 ~ 255.255.255.254

回环地址:127.0.0.1,指本机,一般用于测试使用。查看IP命令:ipconfig 测试IP命令:ping D.D.D.D

2.3 Port: 端口号

端口号:在通信实体上进行网络通讯程序的唯一标识。

  • 一个程序可以占用多个端口号,但是一个端口号只能被一个程序使用。

端口分类:

  • 公认端口:0~1023
  • 注册端口:1024~49151
  • 动态或私有端口:49152~65535

常用端口:

  • MySql:3306 Oracle:1521 Tomcat:8080
  • SMTP:25 Web服务器:80、443 FTP服务器:21

3 计算机网络编程

3.1 InetAddress类

概念:表示互联网协议(IP)地址对象,封装了与该IP地址相关的所有信息,并提供获取信息的常用方法。

常用方法:

  • public static InetAddress getLocalHost() 获得本地主机地址对象
  • public static InetAddress getByName(String host) 根据主机名称获得地址对象
  • public static InetAddress[] getAllByName(String host) 获得所有相关地址对象
  • public String getHostAddress() 获取IP地址字符串
  • public String getHostName() 获得IP地址主机名

代码演示:

public class TestInetAddress {
    public static void main(String[] args) throws Exception{
        //1 表示本机
        InetAddress ia1 = InetAddress.getLocalHost();
        System.out.println("ip地址:"+ia1.getHostAddress()+"主机名:"+ia1.getHostName());
        InetAddress ia2 = InetAddress.getByName("10.9.48.125");
        System.out.println("ip地址:"+ia2.getHostAddress()+"主机名:"+ia2.getHostName());
        InetAddress ia3 = InetAddress.getByName("127.0.0.1");
        System.out.println("ip地址:"+ia3.getHostAddress()+"主机名:"+ia3.getHostName());
        InetAddress ia4 = InetAddress.getByName("localhost");
        System.out.println("ip地址:"+ia4.getHostAddress()+"主机名:"+ia4.getHostName());
        //2 表示局域网地址
        System.out.println("-----------------");
        InetAddress ia5 = InetAddress.getByName("10.9.48.167");
        System.out.println("ip地址:"+ia5.getHostAddress()+"主机名:"+ia5.getHostName());
        //3 表示外网地址
        InetAddress ia6 = InetAddress.getByName("www.mihoyo.com");
        System.out.println("ip地址:"+ia6.getHostAddress()+"主机名:"+ia6.getHostName());

        InetAddress[] allByName = InetAddress.getAllByName("www.mihoyo.com");
        for (InetAddress inetAddress : allByName) {
            System.out.println(inetAddress.getHostAddress());
        }
    }
}

3.2 基于TCP的Socket网络编程

  • Socket(套接字)由操作系统提供的统一网络编程接口,是网络中的一个通信节点。
  • TCP协议分为客户端Socket与服务器ServerSocket。
  • 通信要素:IP地址 + 端口号。

开发步骤

  • 服务器端

    • (1) 创建ServerSocket对象,并指定端口号

    • (2) 侦听客户端连接,返回客户端套接字

    • (3) 获取输入输出流

    • (4) 处理数据

    • (5) 关闭资源

代码演示:

public class TcpServer {
    public static void main(String[] args) throws Exception{
        //1 创建serverSocket 套接字对象,并指定端口号
        ServerSocket listener=new ServerSocket(10086);
        System.out.println("服务器已启动...");
        //2 侦听客户端连接,并返回客户端套接字,注意: accept()阻塞方法, 直到有客户端连接
        Socket socket = listener.accept();
        //3 获取输入,输出流
        InputStream is = socket.getInputStream();
        BufferedReader br=new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
        OutputStream os = socket.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
        //4 处理数据
        //4.1 接收
        String data = br.readLine();
        System.out.println("客户说:"+data);
        //4.2 回复
        bufferedWriter.write("老地方见...");
        bufferedWriter.newLine();
        bufferedWriter.flush();
        //5关闭
        br.close();
        bufferedWriter.close();
        socket.close();
        listener.close();
    }
}
  • 客户端

    • (1)创建客户端套接字,并指定服务器的地址和端口号

    • (2)获取输入输出流

    • (3)处理数据

    • (4)关闭资源

public class TcpClient {
    public static void main(String[] args) throws Exception{
        //(1)创建客户端套接字,并指定服务器的地址和端口号
        Socket socket = new Socket("10.9.48.175",10086);
        //(2)获取输入输出流
        OutputStream os = socket.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter(
            new OutputStreamWriter(os, StandardCharsets.UTF_8)
        );
        InputStream is = socket.getInputStream();
        BufferedReader br=new BufferedReader(
            new InputStreamReader(is, StandardCharsets.UTF_8)
        );
        //(3)处理数据
        //3.1 写入
        bufferedWriter.write("好久不见...");
        bufferedWriter.newLine();
        bufferedWriter.flush();
        //3.2 读取
        String reply = br.readLine();
        System.out.println("服务器回复:"+reply);
        //(4)关闭资源
        bufferedWriter.close();
        br.close();
        socket.close();
    }
}

课堂案例

TCP编程实现客户端上传文件给服务器端

代码演示

TestFileServer:

public class TestFileServer {
    public static void main(String[] args) throws IOException {
        //1 创建
        ServerSocket listener = new ServerSocket(10010);
        //2 监听用户请求
        Socket socket = listener.accept();
        //3 获取输入流
        InputStream inputStream = socket.getInputStream();
        BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
        //4 处理
        FileOutputStream fileOutputStream = new FileOutputStream("e:\\111.png");
        byte[] bytes = new byte[1024 * 4];
        int len = -1;
        while ((len=bufferedInputStream.read(bytes))!=-1) {
            fileOutputStream.write(bytes,0,len);
        }
        //5 关闭
        fileOutputStream.close();
        bufferedInputStream.close();
        socket.close();
        listener.close();
        System.out.println("接受完毕...");
    }
}

TestFileClient:

public class TestFileClient {
    public static void main(String[] args) throws Exception{
        //1 创建
        Socket socket = new Socket("10.9.48.124", 10010);
        //2 获取
        OutputStream outputStream = socket.getOutputStream();
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
        //3 处理
        FileInputStream fileInputStream = new FileInputStream("E:\\QianFeng\\分享演讲\\排球队视频_end.mp4");
        byte[] bytes = new byte[1024 * 4];
        int len;
        while ((len=fileInputStream.read(bytes))!=-1) {
            bufferedOutputStream.write(bytes,0,len);
        }
        bufferedOutputStream.flush();
        //4 关闭
        bufferedOutputStream.close();
        fileInputStream.close();
        socket.close();
        System.out.println("发送完毕...");
    }
}

TCP实现多个客户端发送数据给服务器端

代码演示

ChatServer:

public class ChatServer {
    public static void main(String[] args) throws IOException {
        ServerSocket listener = new ServerSocket(11008);
        System.out.println("聊天室已启动...");
        ExecutorService es = Executors.newCachedThreadPool();
        while (true) {
            Socket socket = listener.accept();
            System.out.println(
                socket.getInetAddress().getHostAddress()+"进入聊天室..."
            );
            //开启子线程来接收数据
            es.submit(new HandleSocket(socket));
        }
    }

    static class HandleSocket implements Runnable {
        private final Socket socket;

        public HandleSocket(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            if (socket != null) {
                BufferedReader br = null;
                try {
                    InputStream is = socket.getInputStream();
                    br = new BufferedReader(
                        new InputStreamReader(is, StandardCharsets.UTF_8)
                    );
                    String data;
                    while ((data = br.readLine())!=null) {
                        System.out.println(
                            socket.getInetAddress().getHostAddress()+"说:"+data
                        );
                    }
                    System.out.println(
                        socket.getInetAddress().getHostAddress()+"正常退出了聊天室..."
                    );
                } catch (Exception e) {
                    System.out.println(
                        socket.getInetAddress().getHostAddress()+"异常退出了聊天室..."
                    );
                } finally {
                    try {
                        br.close();
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

ChatClient:

public class ChatClient {
    public static void main(String[] args) throws IOException {
        //1 创建
        Socket socket = new Socket("10.9.48.185", 9999);
        //2 获取输出流
        OutputStream os = socket.getOutputStream();
        BufferedWriter bw = new BufferedWriter(
        	new OutputStreamWriter(os, StandardCharsets.UTF_8)
        );
        //3 处理
        Scanner input = new Scanner(System.in);
        while (true) {
            String data = input.next();
            bw.write(data);
            bw.newLine();
            bw.flush();
            if (data.equals("over")) {
                break;
            }
        }
        bw.close();
        socket.close();
    }
}

3.3 基于UDP协议的Socket编程

  • DatagramSocket:数据包套接字 (快递站)
  • DatagramPacket:数据报包,用来发送或接收数据包。(快递包裹)

开发步骤

  • 接收方
    • 创建DatagramSocket对象,并指定端口
    • 创建接收数据报包 DatagramPacket
    • 接收处理
    • 关闭资源

代码演示:

public class Receiver {
    public static void main(String[] args) throws Exception {
        //1创建DatagramSocket 对象
        DatagramSocket ds = new DatagramSocket(6666);
        //2创建接收数据报包
        byte[] buf = new byte[1024 * 64];
        DatagramPacket dp = new DatagramPacket(buf, buf.length);
        //3接收 ,阻寨方法,直到接收到数据报包
        System.out.println("准备接收.......");
        ds .receive(dp);
        //4处理
        // dp.getData() 接收的数据
        // dp.getLength() 际接收的数据长度
        String data = new String(dp.getData(),0,dp.getLength());
        System.out.println("发送说:" + data);
        //5关闭
        ds.close();
    }
}
  • 发送方
    • 创建DatagramSocket对象,默认随机绑定一个端口号
    • 创建发送数据报包 DatagramPacket
    • 发送
    • 关闭资源

代码演示:

public class Sender {
    public static void main(String[] args) throws Exception{
        //1创建 DatagramSocket对象,随机绑定一个端口号
        DatagramSocket ds = new DatagramSocket();
        //2创建发送数据报包
        String s="好久不见";
        DatagramPacket dp=new DatagramPacket(
                s.getBytes(),//发送数据
                s.getBytes().length,//发送数据的长度
                InetAddress.getByName( "10.9.48.175"),//对方ip地址
                6666); //对方端口号
        //3 发送
        ds . send(dp);
        //4关闭
        ds.close();
    }
}

课堂案例

使用UDP实现广播发送

代码演示:

ChatReceiver:

public class ChatReceiver {
    public static void main(String[] args) throws Exception{
        //1创建Datagramsocket对象
        DatagramSocket ds=new DatagramSocket(8888);
        //2创建接收数据报包
        byte[] buf=new byte[1024*64];
        DatagramPacket dp=new DatagramPacket(buf,buf.length);
        //3接收
        System.out.println("聊天室已启动...");
        while(true) {
            ds.receive(dp);
            //4处理
            String data = new String(dp.getData(), 0, dp.getLength());
            System.out.println(dp.getAddress().getHostAddress() + "说:" + data);
        }
        //5关闭
        //ds.close();
    }
}

ChatSender:

public class ChatSender {
    public static void main(String[] args) throws Exception {
        DatagramSocket ds=new DatagramSocket();
        Scanner input=new Scanner(System.in);
        while(true) {
            String data=input .next();
            //2创建发送教据报包
            DatagramPacket dp=new DatagramPacket(
                    data.getBytes(),
                    data.getBytes().length,
                    InetAddress.getByName("10.9.48.255"),//10.9.48.255 广播地址
                    8888
            );
            //3发送
            ds.send(dp);
            if(data.equals("over")){
                break;
            }
            //4关闭
            ds.close();
        }
    }
}

你可能感兴趣的:(从零学Java,计算机网络,php,网络)