Java的网络编程简单使用

本文详细介绍了计算机网络的基础知识,包括网络的概念、计算机网络模型如OSI和TCP/IP模型的各层功能。重点讲解了TCP和UDP协议的区别,以及IP地址的分类。此外,还展示了基于TCP协议的客户端和服务端通信案例,以及基于UDP协议的简单通信。最后,提到了HTTP协议在下载图片到本地的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网络编程

一、什么是网络

1.1概念

  • 由点和线构成,表示多个对象间的相互联系

1.2计算机网络

  • 为了实现资源共享和信息传递,通过通信线路连接起来的若干主机(Host)

  • 常见的计算机网络

    • 互联网:点与点之间相连
    • 万维网:端与端之间相连
    • 物联网:物与物之间相连
    • 网络编程:让计算机与计算机之间进行建立连接,实现通信

1.3网络模型

  • OSI参考模型
    • OSI:开放式系统互联
      • 是ISO组织再21985年研究的网络互联模型
      • 体系结构的标准定义了网络互联的七层框架

在这里插入图片描述

  • 每层功能:

    • 第七层:应用层负责文件访问和管理、可靠运输服务、远程操作服务(HTTP、 FTP、 SMTP)

    • 第六层:表示层负责定义转换数据格式及加密,允许选择以二进制或ASCI格式传输

    • 第五层:会话层负责使应用建立和维持会话,使通信在失效时继续恢复通信(断点续传)

    • 第四层:传输层负责是否选择差错恢复协议、数据流重用、错误顺序重排(TCP、 UDP)

    • 第三层:网络层负责定义了能够标识所有网络节点的逻辑地址。 (IP地址)

    • 第二层:链路层在物理层上,通过规程或协议(差错控制)来控制传输数据的正确性。(MAC)

    • 第一层:物理层为设备之间的数据通信提供传输信号和物理介质。(双绞线、 光导纤维)

  • TCP/IP模型

    • TCP/IP模型是因特网使用的参考模型,基于TCP/IP的参考模型将协议分成四个层次
    • 该模型最重要的两个协议就是TCP/IP协议

在这里插入图片描述

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

1.4网络编程总结

  1. 什么是计算机网络
    • 为了实现资源共享和信息传递,通过传输介质将若干主机连接到一起的网络
  2. 计算机网络模型
    • OSI:
      • 应用层 主要指的是程序
      • 表示层 将数据加密或者解密转换成二进制数据
      • 会话层 保持主机与主机之间的连接
      • 传输层 通过网络协议传输数据(TCP/UDP协议)
      • 网络层 分配IP地址
      • 数据链路层 保证准确性(MAC地址 物理地址)
      • 物理层 进行数据传输
    • TCP/IP模型
      • 应用层
      • 传输层
      • 网络层
      • 网络接口层
  3. 网络编程需要什么
    1. 通信协议(TCP、UDP、HTTP)
    2. IP地址
    3. 端口号
  4. 网络编程三要素:协议、地址、端口号

1.5 TCP/UDP

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

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

    • 是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB

1.6 IP

  • IP协议: Internet Protocol Address互联网协议地址/网际协议地址

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

    • IPV4: 4字节32位整数,并分成4段8位的二进制数,每8位之间用圆点隔开,每8位整数可以转换为一个0~255的十进制整数
      • 格式: D.D.D.D
      • 例如: 255.255.255.255
    • IPV6: 16字节128位整数,并分成8段十六进制数,每16位之间用圆点隔开,每16位整数可以转换为一个0~65535的十进制数
      • 格式: X.X.X.X.X.X.X.X
      • 例如: FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF
  • 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
  • DNS 域名解析 将域名解析成IP地址一个域名只能对应一个ip地址 一个ip地址可以对应多个域名

1.7 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地址主机名

二、端口号

2.1概述

  • 网络编程三要素之端口号:

  • 概念:

    • 端口号是之每一个设备程序的唯一数字标识
  • 端口分类:

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

    • MySql: 3306
    • Oracle: 1521
    • redis:6379
    • Tomcat: 8080
    • SMTP: 25
    • Web服务器: 80
    • FTP服务器: 21
  • 总结:

    • 以后自己写的程序端口号最好设置在1024-65535之间

三、通信协议

3.1概述

  • 概念:

    • TCP:传输协议

      • 特点:面向连接,安全可靠,效率低,基于字节流进行通信,数据大小无限制 建立连接三次握手,断开连接四次挥手
    • UDP:数据报协议

      • 特点:面向无连接,不安全,基于数据包的形式通信,数据包大概在64kb

四、基于TCP协议通信

4.1案例1

  • 通过客户端向服务端发送
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws IOException {
        //建立客户端对象
        Socket socket = new Socket("localhost", 999);

        //通过socket对象创建输出流
        OutputStream out = socket.getOutputStream();

        //通过输出流写出内容到服务端
        out.write("hello".getBytes());

        //释放资源
        out.close();
        socket.close();
    }
}


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

public class Server {
    public static void main(String[] args) throws IOException {
        //创建服务端Socket对象
        ServerSocket ss =new ServerSocket(999);

        //通过new ServerSocket对象获取Socket对象
        System.out.println("服务端已启动");
        Socket socket = ss.accept();
		
        //当客户端发送数据到客户端才会执行
        //通过Socket对象获取输入流
        InputStream in = socket.getInputStream();

        //通过输入流读取数据
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf))!=-1){
            String str =new String(buf,0,len);
            System.out.println(str);
        }

        //释放资源
        in.close();
        socket.close();
        ss.close();
    }

}

案例二 基于TCP协议多线程通信

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);

        while (true) {
            //创建客户端Socket对象
            Socket socket = new Socket("localhost", 9898);


            //创建输出流对象
            OutputStream out = socket.getOutputStream();

            //通过输出流写数据
            String words = sc.next();
            if(words.equals("886")){
                break;
            }

            //将用户输入的信息转化成字节
            out.write(words.getBytes());

            out.close();
            socket.close();
        }
        sc.close();
    }
}

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 Server {
    public static void main(String[] args)throws Exception {
        //创建服务端Socket对象
        ServerSocket ss = new ServerSocket(9898);

        //创建Socket对象
        System.out.println("服务端已启动");
        while (true) {
            //阻塞式方法 来一个创建一个
            Socket socket = ss.accept();
            String ip = socket.getInetAddress().getHostAddress();

            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        InputStream in = socket.getInputStream();
                        //读取客户端发送的数据
                        BufferedReader br = new BufferedReader(new InputStreamReader(in));
                        String line;
                        while ((line=br.readLine())!=null){
                            System.out.println(ip+":"+line);
                        }
                        br.close();
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

案例三

  • 实现客户端文件上传功能
import java.io.*;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws IOException {
        //实现上传功能
        //创建Socket对象
        Socket socket = new Socket("localhost", 9897);

        //创建输出流
        OutputStream out = socket.getOutputStream();

        //模拟文件上传fis指的是上传的文件
        FileInputStream fis = new FileInputStream("C:\\Users\\24826\\Desktop\\a.jpg");

        byte[] buf = new byte [1024];
        int len;
        while ((len=fis.read(buf))!=-1){
            out.write(buf,0,len);
        }

        //告知服务器写完了
        socket.shutdownOutput();

        //服务短返回上传成功
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        System.out.println(br.readLine());

        //释放资源
        fis.close();
        out.close();
        socket.close();
    }
}

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(9897);

        while (true) {
            Socket socket = ss.accept();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        InputStream in = socket.getInputStream();
                        //文件重名问题 1.时间戳+5位随机数(时间的毫秒数)2.UUID 3.雪花算法
                        String fileName = UUID.randomUUID().toString().replace("-", "");
                        FileOutputStream fos = new FileOutputStream(fileName + ".jpg");
                        byte[] buf = new byte[1024];
                        int len;
                        while ((len=in.read(buf))!=-1){
                            fos.write(buf,0,len);
                        }
                        OutputStream out = socket.getOutputStream();
                        out.write("上传成功".getBytes());

                         out.close();
                         fos.close();
                         in.close();
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    //解决文件重名问题

                }
            }).start();
        }
    }
}

五、基于UDP协议通信

5.1案例

  • 发送端发送数据到接收端
import java.io.IOException;
import java.net.*;

public class Send {
    public static void main(String[] args) throws IOException {
        //基于UDP协议创建Socket对象  无序指定端口号协议
        DatagramSocket ds = new DatagramSocket();

        //2.创建数据包对象
        byte[] buf = "你好接收端".getBytes();

        DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("localhost"), 9999);
        //发送数据包
        ds.send(dp);
        //释放资源
        ds.close();
    }
}

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Receive {
    public static void main(String[] args) throws  Exception{
        //1.基于UDP协议创建Socket对象
        DatagramSocket ds = new DatagramSocket(9999);

        //2.创建数据包对象
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf, buf.length);

        //3.接受数据包
        ds.receive(dp);

        //4.解析数据包数据
        //从数据包中获取数据
        byte[] data = dp.getData();

        //从数据包中获取InetAddress对象
        InetAddress inetAddress = dp.getAddress();

        //从数据包中获取端口号
        int port = dp.getPort();

        //获取数据包的数据字节长度
        int length = dp.getLength();

        String str = new String(data, 0, length);

        System.out.println("ip"+inetAddress.getHostAddress());
        System.out.println("port"+port);
        System.out.println("data"+data);

        //5.释放资源
        ds.close();
    }
}

六、基于HTTP协议通信

6.1案例1

  • 通过HTTP协议下载图片到本地
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        //实现使用http协议通信  从服务端下载一张图片

        //创建URL对象
        URL url = new URL("https://img10.360buyimg.com/cms/jfs/t1/115449/27/29260/131972/631902deE0c0f8dab/9288fcd9d35fddde.jpg");

        //通过服务器连接对象
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        //判断连接是否成功
        if (connection.getResponseCode()==200){
            //获取输入流对象
            InputStream in = connection.getInputStream();

            FileOutputStream fos = new FileOutputStream("download\\" + UUID.randomUUID().toString().replace("-", "")+".jpg");
            byte[] buf = new byte[1024];
            int len;
            while ((len=in.read(buf))!=-1){
                fos.write(buf,0,len);
            }

            System.out.println("success");

            //释放资源
            fos.close();
            in.close();
            connection.disconnect();

        }
    }
}

connection.getInputStream();

        FileOutputStream fos = new FileOutputStream("download\\" + UUID.randomUUID().toString().replace("-", "")+".jpg");
        byte[] buf = new byte[1024];
        int len;
        while ((len=in.read(buf))!=-1){
            fos.write(buf,0,len);
        }

        System.out.println("success");

        //释放资源
        fos.close();
        in.close();
        connection.disconnect();

    }
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值