【JavaSE】网络编程学习笔记

发布于:2025-06-30 ⋅ 阅读:(20) ⋅ 点赞:(0)

网络编程

-网络相关概念

  • 网络通信

    1. 概念:两台设备之间通过网络实现数据传输
    2. 网络通信:将数据通过网络从一台设备传输到另一台设备
    3. java.net包下提供了一系列的类或接口,供程序员使用,完成网络通信
  • 网络

    1. 概念:两台或多台设备通过一定物理设备连接起来构成了网络
    2. 根据网络的覆盖范围不同,对网络进行分类:
      1. 局域网:覆盖范围最小,仅仅覆盖一个教室或一个机房
      2. 城域网:覆盖范围较大,可以覆盖一个城市
      3. 广域网:覆盖范围最大,可以覆盖全国,甚至全球,万维网是广域网的代表
  • IP地址

    1. 概念:用于唯一标识网络中的每台计算机
    2. 查看IP地址:ipconfig
    3. IP地址的表示形式:点分十进制xx.xx.xx.XX
    4. 每一个十进制数的范围:0~255
    5. IP地址的组成=网络地址+主机地址,比如:192.168.16.69
    6. lPv6是互联网工程任务组设计的用于替代IPv4的下一代IP协议,其地址数量号称可以为全世界的每一粒沙子编上一个地址
    7. 由于IPv4最大的问题在于网络地址资源有限,严重制约了互联网的应用和发展。IPv6的使用,不仅能解决网络地址资源数量的问题,而且也解决了多种接入设备连入互联网的障碍
  • 域名

    1. www.baidu.com
    2. 好处:为了方便记忆,解决记ip的困难
    3. 概念:将ip地址映射成域名
  • 端口号

    1. 概念:用于标识计算机上某个特定的网络程序

    2. 表示形式:以整数形式,范围0~65535

    3. 0~1024已经被占用,比如 ssh 22, ftp 21,smtp 25 http 804

    4. 常见的网络程序端口号:

      tomcat :8080

      mysql:3306

      oracle:1521

      sqlserver:1433

  • 网络通信协议

    协议(tcp/ip)

    TCP/lP(Transmission Control Protocol/Internet Protocol)的简写中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是Internet最基本的协议、Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的。

  • TGP 和 UDP

    TCP协议:

    1. 使用TCP协议前,须先建立TCP连接,形成传输数据通道
    2. 传输前,采用"三次握手"方式,是可靠的
    3. TCP协议进行通信的两个应用进程:客户端、服务端
    4. 在连接中可进行大数据量的传输
    5. 传输完毕,需释放已建立的连接,效率低

    UDP协议:

    1. 将数据、源、目的封装成数据包,不需要建立连接
    2. 每个数据报的大小限制在64K内
    3. 因无需连接,故是不可靠的
    4. 发送数据结束时无需释放资源(因为不是面向连接的),速度快
    5. 举例: 厕所通知: 发短信

-InetAddress类

  • 相关方法

    1. 获取本机InetAddress对象 getLocalHost
    2. 根据指定主机名/域名获取ip地址对象 getByName
    3. 获取InetAddress对象的主机名 getHostName
    4. 获取InetAddress对象的地址 getHostAddress
  • 练习

    package inetaddress;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    /**
     * 1. 获取本机InetAddress对象 getLocalHost
     * 2. 根据指定主机名/域名获取ip地址对象 getByName
     * 3. 获取InetAddress对象的主机名 getHostName
     * 4. 获取InetAddress对象的地址 getHostAddress
     */
    public class Practice1 {
        public static void main(String[] args) throws UnknownHostException {
            InetAddress inetAddress=null;
            //1. 获取本机InetAddress对象 getLocalHost
            inetAddress=InetAddress.getLocalHost();
            System.out.println(inetAddress);
            //2. 根据指定主机名/域名获取ip地址对象 getByName
            inetAddress=InetAddress.getByName("DESKTOP-DVFTQAF");
            System.out.println(inetAddress);
            inetAddress=InetAddress.getByName("www.google.com");
            System.out.println(inetAddress);
            //3. 获取InetAddress对象的主机名 getHostName
            String hostName=inetAddress.getHostName();
            System.out.println(hostName);
            //4. 获取InetAddress对象的地址 getHostAddress
            String hostAddress=inetAddress.getHostAddress();
            System.out.println(hostAddress);
        }
    }
    

-Socket

  • 基本介绍
    1. 套接字(Socket)开发网络应用程序被广泛采用,以至于成为事实上的标准。
    2. 通信的两端都要有Socket,是两台机器间通信的端点
    3. 网络通信其实就是Socket间的通信。
    4. Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输
    5. 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端

-TCP网络通信编程

  • 基本介绍

    1. 基于客户端一服务端的网络通信
    2. 底层使用的是TCP/IP协议
    3. 应用场景举例:客户端发送数据,服务端接受并显示
    4. 基于Socket的TCP编程
  • TCP字节流编程案例

    • 服务端代码

      package socket;
      
      import java.io.*;
      import java.net.ServerSocket;
      import java.net.Socket;
      
      /**
       * 1.编写一个服务器端, 和一个客户端
       * 2.服务器端在 9999端口监听!
       * 2.客户端连接到服务器端,发送"hello,server”,并接收服务器端回发的"hello,client",再退出
       * 4. 服务器端接收到 客户端发送的 信息,输出,并发送"hello, client",再退出
       */
      public class SocketTCPTest01Server {
          public static void main(String[] args) throws IOException {
              //创建服务器端套接字
              ServerSocket serverSocket=new ServerSocket(9999);
              System.out.println("服务端等待连接,端口:9999");
      
              //监听连接并返回一个连接套接字
              Socket socket=serverSocket.accept();
              System.out.println("服务端建立连接成功,可以读取数据");
      
              //获取连接输入流,读取数据并打印
              InputStream inputStream=socket.getInputStream();
              byte[] bytes=new byte[1024];
              int readlen;
              while((readlen= inputStream.read(bytes))!=-1){
                  System.out.print("读取到数据:"+new String(bytes,0,readlen));
              }
              System.out.println();
      
              //获取连接输出流,输出信息
              String str="hello,client";
              OutputStream outputStream=socket.getOutputStream();
              outputStream.write(str.getBytes());
              socket.shutdownOutput();
              System.out.println("服务端发送数据成功");
      
              //关闭流及套接字
              inputStream.close();
              outputStream.close();
              socket.close();
              System.out.println("服务端已关闭流及连接");
          }
      }
      
      
    • 客户端代码

      package socket;
      
      import java.io.*;
      import java.net.InetAddress;
      import java.net.Socket;
      import java.net.UnknownHostException;
      
      /**
       * 1.编写一个服务器端, 和一个客户端
       * 2.服务器端在 9999端口监听!
       * 2.客户端连接到服务器端,发送"hello,server”,并接收服务器端回发的"hello,client",再退出
       * 4. 服务器端接收到 客户端发送的 信息,输出,并发送"hello, client",再退出
       */
      public class SocketTCPTest01Client {
          public static void main(String[] args) throws IOException {
              //获取主机的网络信息
              InetAddress inetAddress=InetAddress.getLocalHost();
      
              //创建套接字
              Socket socket=new Socket(inetAddress,9999);
              System.out.println("客户端获取套接字成功");
      
              //获取输出流,发送数据及结束标识
              String str="hello,server";
              OutputStream outputStream=socket.getOutputStream();
              outputStream.write(str.getBytes());
              System.out.println("客户端发送数据成功");
              socket.shutdownOutput();
      
              //获取连接输入流,读取数据并打印
              InputStream inputStream=socket.getInputStream();
              byte[] bytes=new byte[1024];
              int readlen;
              while((readlen= inputStream.read(bytes))!=-1){
                  System.out.print("读取到数据:"+new String(bytes,0,readlen));
              }
              System.out.println();
      
              //关闭流与套接字
              outputStream.close();
              inputStream.close();
              socket.close();
              System.out.println("客户端已关闭流及连接");
          }
      }
      
      
  • TCP字符流编程案例

    • 服务端

      package socket;
      
      import java.io.*;
      import java.net.ServerSocket;
      import java.net.Socket;
      
      /**
       * 编写一个服务端,和一个客户端服务端,使用字符流传输
       * 在 9999端口监听
       * 客户端连接到服务端,发送"helo, server”,并接收服务端回发的"hello,client”,再退出
       * 服务端接收到 客户端发送的 信息,输出,并发送"hello, client",再退出
       */
      public class SocketTCPTest02Server {
          public static void main(String[] args) throws IOException {
              //创建服务端套接字并指定端口
              ServerSocket serverSocket=new ServerSocket(9999);
              System.out.println("等待接收连接");
      
              //阻塞等待接受连接
              Socket socket=serverSocket.accept();
              System.out.println("收到连接");
      
              //字符流读取数据
              String str;
              BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
              while((str=bufferedReader.readLine())!=null){
                  System.out.println(str);
              }
              System.out.println("读取数据结束");
      
              //字符流发送数据
              BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
              bufferedWriter.write("hello, client");
              bufferedWriter.flush();
              socket.shutdownOutput();
      
              //关闭流与套接字
              bufferedReader.close();
              bufferedWriter.close();
              socket.close();
              System.out.println("已关闭流与套接字");
          }
      }
      
    • 客户端

      package socket;
      
      import java.io.*;
      import java.net.InetAddress;
      import java.net.Socket;
      
      /**
       * 编写一个服务端,和一个客户端服务端,使用字符流传输
       * 在 9999端口监听
       * 客户端连接到服务端,发送"helo, server”,并接收服务端回发的"hello,client”,再退出
       * 服务端接收到 客户端发送的 信息,输出,并发送"hello, client",再退出
       */
      public class SocketTCPTest02Client {
          public static void main(String[] args) throws IOException {
              //创建套接字
              Socket socket=new Socket(InetAddress.getLocalHost(),9999);
              System.out.println("客户端获取套接字成功");
      
              //获取输出流,发送数据及结束标识
              BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
              bufferedWriter.write("hello, server");
              bufferedWriter.flush();
              socket.shutdownOutput();
              System.out.println("客户端发送数据结束");
      
              //获取连接输入流,读取数据并打印
              String str;
              BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
              while((str=bufferedReader.readLine())!=null){
                  System.out.println(str);
              }
              System.out.println("读取数据结束");
      
              //关闭流与套接字
              bufferedWriter.close();
              bufferedReader.close();
              socket.close();
              System.out.println("客户端已关闭流及连接");
          }
      }
      
  • TCP文件传输案例

    • 服务端

      package socket;
      
      import java.io.*;
      import java.net.ServerSocket;
      import java.net.Socket;
      import java.nio.file.Files;
      import java.nio.file.Paths;
      
      /**
       * (1)编写客户端程序和服务器端程序
       * (2)客户端可以传输一个图片文件名给服务端,比如奥迪.jpg,
       * (3)服务端收到图片名后,从D:\temp\source读取对应图片文件,并客户端返回这个图片文件,如果服务器没有这个文件,返回一个默认的图片即可。
       * (3)客户端收到文件后,保存到本地D:\temp\target\
       *
       * 运行提示:
       * 1. 创建好D:\temp\target\和D:\temp\source这两个文件夹
       * 2. 在D:\temp\source中存储一张"奥迪.jpg"和“无名.jpg”
       */
      public class SocketTCPFileTestServer {
          //源文件目录路径
          private static final String SOURCE_FOLDER_PATH="D:\\temp\\source\\";
      
          public static void main(String[] args) throws IOException {
              //1.创建socket服务器对象,并获取连接
              ServerSocket serverSocket=new ServerSocket(9999);
              System.out.println("等待客户端连接...");
              Socket socket=serverSocket.accept();
              System.out.println("获取来自客户端的连接:"+socket.getInetAddress());
      
              //2.获取接收到的文件名
              InputStreamReader inputStreamReader=new InputStreamReader(socket.getInputStream());
              StringBuilder stringBuilder= new StringBuilder();
              char[] chars=new char[32];
              int len=0;
              while((len=inputStreamReader.read(chars))!=-1){
                  stringBuilder.append(new String(chars,0,len));
              }
              String fileName=stringBuilder.toString();
              System.out.println("获取文件名完成:"+fileName);
      
              //3.判断要获取的文件名,如果不是奥迪.jpg,就传输无名.jpg
              if(!"奥迪.jpg".equals(fileName)){
                  fileName="无名.jpg";
              }
      
              //4.读取本地的图片,并发送给客户端
              String filePath=SOURCE_FOLDER_PATH+fileName;
              BufferedInputStream bufferedInputStream=new BufferedInputStream(Files.newInputStream(Paths.get(filePath)));
              BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(socket.getOutputStream());
              byte[] bytes=new byte[1024];
              while(bufferedInputStream.read(bytes)!=-1){
                  bufferedOutputStream.write(bytes);
              }
              bufferedOutputStream.flush();//清除缓存,确认发送
              socket.shutdownOutput();//发送传输结束标志
              System.out.println("读取本地图片并发送给客户端完成");
      
              //4.关闭连接
              inputStreamReader.close();
              bufferedInputStream.close();
              bufferedOutputStream.close();
              socket.close();
              System.out.println("关闭来自"+socket.getInetAddress()+"的连接");
          }
      }
      
    • 客户端

      package socket;
      
      import java.io.*;
      import java.net.InetAddress;
      import java.net.Socket;
      import java.nio.file.Files;
      import java.nio.file.Paths;
      
      /**
       * (1)编写客户端程序和服务器端程序
       * (2)客户端可以传输一个图片文件名给服务端,比如奥迪.jpg,
       * (3)服务端收到图片名后,从D:\temp\source读取对应图片文件,并客户端返回这个图片文件,如果服务器没有这个文件,返回一个默认的图片即可。
       * (3)客户端收到文件后,保存到本地D:\temp\target\
       *
       * 运行提示:
       * 1. 创建好D:\temp\target\和D:\temp\source这两个文件夹
       * 2. 在D:\temp\source中存储一张"奥迪.jpg"和“无名.jpg”
       */
      public class SocketTCPFileTestClient {
          //目标文件目录路径
          private static final String TARGET_FOLDER_PATH="D:\\temp\\target\\";
      
          public static void main(String[] args) throws IOException {
              //1. 与服务器建立链接
              Socket socket=new Socket(InetAddress.getLocalHost(),9999);
              System.out.println("客户端已获取和服务器的链接");
      
              //2.向服务器发送文件名奥迪.jpg
              String fileName="奥迪.jpg";
              OutputStreamWriter outputStreamWriter=new OutputStreamWriter(socket.getOutputStream());
              outputStreamWriter.write(fileName);
              outputStreamWriter.flush();//清除缓存,确认发送
              socket.shutdownOutput();//发送结束传输标志
              System.out.println("客户端已发送文件名:"+fileName);
      
              //3. 接收服务器发送的图片并保存到目标文件目录
              BufferedInputStream bufferedInputStream=new BufferedInputStream(socket.getInputStream());
              BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(Files.newOutputStream(Paths.get(TARGET_FOLDER_PATH+fileName)));
              byte[] bytes=new byte[1024];
              while(bufferedInputStream.read(bytes)!=-1){
                  bufferedOutputStream.write(bytes);
              }
              System.out.println("客户端接收文件完成");
      
              //4. 关闭连接
              outputStreamWriter.close();
              bufferedInputStream.close();
              bufferedOutputStream.close();
              socket.close();
              System.out.println("客户端已关闭连接");
          }
      }