小工具知识网

当前位置: 首页 > 行业知识 > JAVA-网络编程基础

行业知识

JAVA-网络编程基础

2026-11-14 06:50:34 来源:互联网转载

JAVA-网络编程

01. 网络通信

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

02. 网络

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

03. ip地址

1. 基本介绍

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

2. ipv4地址分类

04. 域名

1. 介绍

  1. www.baidu.com
  2. 好处:为了方便记忆,解决记ip的困难
  3. 概念:将ip地址映射成域名,如何映射,http协议

2. 端口号

  1. 概念: 用于标识计算机上某个特定的网络程序
  2. 表示形式:以整数形式,端口范围0 ~ 65535[2个字节表示端口0 ~ 2^16 - 1]
  3. 0 ~ 1024已经被占用,比如 ssh 22,ftp 21, smtp 25,http 80
  4. 常见的网络程序端口
    1. tomcat:8080
    2. mysql:3306
    3. oracle:1521
    4. sqlserver:1433

05. 网络通信协议

1. 网络协议的理解

​ 网络协议是一种规则和约定的集合,用于在计算机网络中进行通信和数据交换。这些规则规定了数据在网络中的传输方式、格式、错误检测和纠正方法等。网络协议使得不同类型的计算机和设备可以互相通信,实现数据的可靠传输和有效交换。

​ 想象一下,网络协议就像人们在进行交流时遵循的语言和礼仪规范。它确保了交流的顺畅和准确,使得信息能够按照一定的格式和流程进行传递。常见的网络协议包括TCP/IP、HTTP、FTP、SMTP等,它们各自负责不同的网络通信任务,如数据传输、网页浏览、文件下载、电子邮件发送等。

2. 协议(TCP/IP)

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

3. 模型

06. TCP和UDP

1. TCP协议:传输控制协议

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

2. UDP协议:用户数据协议

  1. 将数据、源、目的封装成数据包,不需要建立连接
  2. 每个数据报的大小限制在64K内,不适合传输大量数据
  3. 因无需连接,故是不可靠的
  4. 发送数据结束时无需释放资源(因为不是面向连接的),速度快

07. InetAddress类

1. 相关方法

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

2. 应用案例

要求:编写代码, 获取计算机的主机名和IP地址的相关API

import java.net.InetAddress;import java.net.UnknownHostException;/** *  演示InetAddress类 */public class API_ {    public static void main(String[] args) throws UnknownHostException {        //1. 获取本机的InetAddress对象        InetAddress inetAddress = InetAddress.getLocalHost();        System.out.println(inetAddress);//1.1 显示计算机名+ip        //2. 根据指定主机名 获取InetAddress对象        InetAddress host1 = InetAddress.getByName("kratolt");        System.out.println("host1= " + host1);        //3. 根据域名返回 InetAddress对象, 比如www.baidu.com 对应的        InetAddress host2 = InetAddress.getByName("www.baidu.com");        System.out.println(host2);        //4. 通过 InetAddress 对象,获取对应的地址        String hostAddress = host2.getHostAddress();        System.out.println("host2对应的ip= " + hostAddress);        //5. 通过InetAddress 对象,获取对应的主机名、或者域名        String hostName = host2.getHostName();        System.out.println("host2对应的主机名/域名" + hostName);    }}

08. Socket

1. 基本介绍

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

2. 示意图

当我们需要通讯的时候(读写数据)
  1. socket.getOutputStream()
  2. socket.getInputStream()
Socket 的理解
  1. TCP编程,可靠
  2. UDP编程,不可靠
  3. 客户端和服务器在通常情况下,是在不同主机的。碍于本人,客户端和服务器端在一台主机

09. TCP网络通信编程

1. 基本介绍

  1. 给予客户端—服务端的网络通信
  2. 底层使用的是TCP/IP协议
  3. 基于Socket的TCP编程

2. 应用案例1(使用字节流)

  1. 编写一个服务器端和一个客户端
  2. 服务器端在9999端口监听
  3. 客户端连接到服务器端,发送“hello,server!”,然后退出
  4. 服务器端接收到 客户端发的信息,输出,退出

    服务端类:

import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;/** * 服务端 */public class SocketTCP01Server {    public static void main(String[] args) throws IOException {        //思路:        //1. 在本机的9999端口监听,等待连接        //1.1 细节:要求在本机没有其他服务在监听9999        //1.2 细节:这个ServerSocket 可以通过accept() 返回多个Socket[多个客户端连接服务器的并发]        ServerSocket serverSocket = new ServerSocket(9999);        System.out.println("服务端,在9999端口监听,等待连接..");        //2. 当有客户端连接9999端口时,程序会阻塞,等待连接        //2.1 如果有客户端连接,则会返回Socket对象,程序继续运行        Socket socket = serverSocket.accept();        System.out.println("服务器端socket = " + socket.getClass());        //3. 通过socket。getInputStream() 读取客户端写入数据到数据通道的数据,显示        InputStream inputStream = socket.getInputStream();        //4. IO读取        byte[] bytes = new byte[1024];        int readLean = 0;        while ((readLean = inputStream.read(bytes)) != -1) {            System.out.println(new String(bytes, 0, readLean));//根据读取到的实际长度,显示内容        }        //5. 关闭流对象和socket        inputStream.close();        socket.close();        serverSocket.close();//关闭    }}

客户端类:

package com.yzjedu.socket_;import java.io.IOException;import java.io.OutputStream;import java.net.InetAddress;import java.net.Socket;/** * 03. 客户端 */public class SocketTCP01Client {    public static void main(String[] args) throws IOException {        //思路        //1. 连接服务端(ip,端口)        //1.1 解读连接本机的9999端口,如果连接成功,返回Socket对象        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);        System.out.println("客户端socket = " + socket.getClass());        //2. 连接上后,生成Socket,通过socket.getOutputStream()        // 得到和socket 对象关联的输出流对象        OutputStream outputStream = socket.getOutputStream();        //3. 通过输出流,写入数据到 数据通道        outputStream.write("hello, server!".getBytes());        //4. 关闭流对象和socket,必须关闭        outputStream.close();        socket.close();    }}

3. 应用案例2(使用字节流)

  1. 编写- -个服务端,和一个客户端
  2. 服务器端在9999端口监听
  3. 客户端连接到服务端,发送"hello, server"并接收服务器端回发的"hello,client",再退出
  4. 服务器端接收到客户端发送的信息,输出,并发送"hello, client", 再退出
  5. 注意:在发送完之后要设置结束标记
    1. 设置写入结束标记socket.shutdownOutput()

服务器端类:

import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;/** * 04. 服务端 */@SuppressWarnings("all")public class SocketTCP02Server {    public static void main(String[] args) throws IOException {        //思路:        //1. 在本机的9999端口监听,等待连接        //1.1 细节:要求在本机没有其他服务在监听9999        //1.2 细节:这个ServerSocket 可以通过accept() 返回多个Socket[多个客户端连接服务器的并发]        ServerSocket serverSocket = new ServerSocket(9999);        System.out.println("服务端,在9999端口监听,等待连接..");        //2. 当有客户端连接9999端口时,程序会阻塞,等待连接        //2.1 如果有客户端连接,则会返回Socket对象,程序继续运行        Socket socket = serverSocket.accept();        System.out.println("服务器端socket = " + socket.getClass());        //3. 通过socket。getInputStream() 读取客户端写入数据到数据通道的数据,显示        InputStream inputStream = socket.getInputStream();        //4. IO读取        byte[] bytes = new byte[1024];        int readLean = 0;        while ((readLean = inputStream.read(bytes)) != -1) {            System.out.println(new String(bytes, 0, readLean));//根据读取到的实际长度,显示内容        }        //5. 获取socket县关联的输出流        OutputStream outputStream = socket.getOutputStream();        outputStream.write("hello, client".getBytes());        socket.shutdownOutput();        //6. 关闭流对象和socket        outputStream.close();        inputStream.close();        socket.close();        serverSocket.close();//关闭    }}

客户端类:

import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.InetAddress;import java.net.Socket;/** * 05. 客户端 */@SuppressWarnings("all")public class SocketTCP02Client {    public static void main(String[] args) throws IOException {        //思路        //1. 连接服务端(ip,端口)        //1.1 解读连接本机的9999端口,如果连接成功,返回Socket对象        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);        System.out.println("客户端socket = " + socket.getClass());        //2. 连接上后,生成Socket,通过socket.getOutputStream()        // 得到和socket 对象关联的输出流对象        OutputStream outputStream = socket.getOutputStream();        //3. 通过输出流,写入数据到 数据通道        outputStream.write("hello, server!".getBytes());        //3.1 设置结束标记        socket.shutdownOutput();        //4. 获取socket关联的输入流,读取数据(字节),并显示        InputStream inputStream = socket.getInputStream();        byte[] bytes = new byte[1024];        int readLen = 0;        while ((readLen = inputStream.read(bytes)) != -1) {            System.out.println(new String(bytes, 0, readLen));        }        //5. 关闭流对象和socket,必须关闭        inputStream.close();        outputStream.close();        socket.close();    }}

4. 应用案例3(使用字符流)

  1. 编写-个服务端,和一个客户端
  2. 服务端在9999端口监听
  3. 客户端连接到服务端,发送"hello, server" ,并接收服务端回发的"hello,client",再退出
  4. 服务端接收到客户端发送的信息,输出,并发送"hello, client",再退出
  5. 注意编写结束标记
    1. shutdownOutput()
    2. write.newLIne()//换行符,注意需要使用readLine()

服务器端:

import java.io.*;import java.net.ServerSocket;import java.net.Socket;@SuppressWarnings("all")public class SocketTCP03Server {    public static void main(String[] args) throws IOException {        //思路:        //1. 在本机的9999端口监听,等待连接        //1.1 细节:要求在本机没有其他服务在监听9999        //1.2 细节:这个ServerSocket 可以通过accept() 返回多个Socket[多个客户端连接服务器的并发]        ServerSocket serverSocket = new ServerSocket(9999);        System.out.println("服务端,在9999端口监听,等待连接..");        //2. 当有客户端连接9999端口时,程序会阻塞,等待连接        //2.1 如果有客户端连接,则会返回Socket对象,程序继续运行        Socket socket = serverSocket.accept();        System.out.println("服务器端socket = " + socket.getClass());        //3. 通过socket。getInputStream() 读取客户端写入数据到数据通道的数据,显示        InputStream inputStream = socket.getInputStream();        //4. IO读取,使用字符流,使用InputStreamReader 将 inputStream 转换成字符流        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));        String s = bufferedReader.readLine();        System.out.println(s);//输出        //5. 获取socket相关联的输出流        OutputStream outputStream = socket.getOutputStream();        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));        bufferedWriter.write("hello, Client 字符流");        bufferedWriter.newLine();        bufferedWriter.flush();        //6. 关闭流对象和socket        bufferedWriter.close();        bufferedReader.close();        inputStream.close();        socket.close();        serverSocket.close();//关闭    }}

客户端:

import java.io.*;import java.net.InetAddress;import java.net.Socket;@SuppressWarnings("all")public class SocketTCP03Client {    public static void main(String[] args) throws IOException {        //思路        //1. 连接服务端(ip,端口)        //1.1 解读连接本机的9999端口,如果连接成功,返回Socket对象        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);        System.out.println("客户端socket = " + socket.getClass());        //2. 连接上后,生成Socket,通过socket.getOutputStream()        // 得到和socket 对象关联的输出流对象        OutputStream outputStream = socket.getOutputStream();        //3. 通过输出流,写入数据到 数据通道,使用字符流        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));        bufferedWriter.write("hello,server 字符流");        //3.1 设置结束标记        bufferedWriter.newLine();//插入一个换行符,表示写入内容结束,注意:要求对方使用readLine()        bufferedWriter.flush();//使用字符流,需要手动刷新,否则不会写入数据通道        //4. 获取socket关联的输入流,读取数据(字节),并显示        InputStream inputStream = socket.getInputStream();        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));        String s = bufferedReader.readLine();        System.out.println(s);        //5. 关闭流对象和socket,必须关闭        bufferedReader.close();        bufferedWriter.close();        outputStream.close();        socket.close();    }}

5. 应用案例4

  1. 编写一个服务端,和一个客户端
  2. 服务器端在8888端口监听
  3. 客户端连接到服务端,发送一-张图片d:\lqie.png
  4. 服务器端接收到客户端发送的图片,保存到Src下,发送"收到图片"再退出
  5. 客户端接收到服务端发送的"收到图片",再退出
  6. 该程序要求使用StreamUtils.java,我们直接使用(在开发里你会经常使用到同事或者公司的开发工具类)

服务器端:

import java.io.*;import java.net.ServerSocket;import java.net.Socket;public class TCPFileUploadServer {    public static void main(String[] args) throws Exception {        //1. 服务端在本机,监听8888        ServerSocket serverSocket = new ServerSocket(8888);        System.out.println("服务端在8888端口监听...");        //2. 等待客户端的连接        Socket socket = serverSocket.accept();        //3. 读取客户端发送的数据        //3.1 通过socket得到一个输入流        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());        byte[] bytes = StreamUtils.streamToByteArray(bis);        //4. 将得到bytes数组,写入到指定的路径,就得到一个文件        String filePath = "src\qie1.png";        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));        bos.write(bytes);        bos.close();        //5. 向客户端回复收到图片        //通过socket 获取到输出流        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));        writer.write("服务器:收到图片");        writer.flush();        socket.shutdownOutput();//设置写入结束标记        //6. 关闭其他流        writer.close();        bis.close();        socket.close();        serverSocket.close();    }}

客户端:

import java.io.*;import java.net.InetAddress;import java.net.Socket;public class TCPFileUploadClient {    public static void main(String[] args) throws Exception {        //1. 创建客户端        Socket socket = new Socket(InetAddress.getLocalHost(), 8888);        //2. 创建读取磁盘的输入流        String filePath = "d:\qie.png";        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));        //2.1bytes 就是 filePath对应的字节数组        byte[] bytes = StreamUtils.streamToByteArray(bis);        //3. 通过socket获取输出流,将bytes数据发送给服务端        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());        bos.write(bytes);//将文件对应的字节数组的内容,写入到数据通道        bos.flush();        bis.close();        socket.shutdownOutput();//设置写入数据的结束标记        //接受从服务器回复的消息        InputStream inputStream = socket.getInputStream();        //使用StreamUtils 的方法,直接将 inputStream 读取到的内容 转成字符串        String s = StreamUtils.streamToString(inputStream);        System.out.println(s);        //4. 关闭相关的流        inputStream.close();        bos.close();        socket.close();    }}

StreamUtils.java:

import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;/** * 此类用于演示关于流的读写方法 * */public class StreamUtils {/** * 功能:将输入流转换成byte[], 即可以把文件的内容读入到byte[] * @param is * @return * @throws Exception */public static byte[] streamToByteArray(InputStream is) throws Exception{ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象byte[] b = new byte[1024];//字节数组int len;while((len=is.read(b))!=-1){//循环读取bos.write(b, 0, len);//把读取到的数据,写入bos}byte[] array = bos.toByteArray();//然后将bos 转成字节数组bos.close();return array;}/** * 功能:将InputStream转换成String * @param is * @return * @throws Exception */public static String streamToString(InputStream is) throws Exception{BufferedReader reader = new BufferedReader(new InputStreamReader(is));StringBuilder builder= new StringBuilder();String line;while((line=reader.readLine())!=null){builder.append(line+"\r\n");}return builder.toString();}}

6. netstat指令

  1. netstat -an可以查看当前主机网络情况,包括端口监听情况和网络连接情况
  2. netstat -an | more可以分页显示
  3. 要求在dos控制台下执行win+r
说明:
  1. Listening表示某个端口在监听
  2. 如果有一个外部程序(客户端)连接到该端口,就会显示一条连接信息.
  3. 可以输入ctrl + C退出指令
  4. 当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口是TCP/IP来分配的,是不确定的,是随机的.
  5. 程序验证+ netstat

10. UDP 网络通信编程[了解]

1. 基本介绍

  1. 类DatagramSocket和DatagramPacket[数据包/数据报]实现了基于UDP协议网络程序。
  2. UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
  3. DatagramPacket对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号
  4. UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接
UDP说明:
  1. 没有明确的服务端和客户端,演变成数据的发送端和接收端
  2. 接收数据和发送数据是通过DatagramSocket对象完成
  3. 将数据封装到DatagramPacket 对象/装包
  4. 当接收到DatagramPacket 对象,需要进行拆包,取出数据
  5. DatagramSocket 可以指定在那个端口接收数据

2. 基本流程

  1. 核心的两个类/对象DatagramSocket与DatagramPacket
  2. 建立发送端,接收端(没有服务端和客户端概念)
  3. 发送数据前,建立数据包/报DatagramPacket对象
  4. 调用DatagramSocket的发送、接收方法
  5. 关闭DatagramSocket

3. 应用案例

  1. 编写一个接收端A,和一一个发送端B
  2. 接收端A在9999端口等待接收数据(接收receive、发送send)
  3. 发送端B向接收端A发送数据"hello ,明天吃火锅~”
  4. 接收端A接收到发送端B发送的数据,回复"好的,明天见",再退出
  5. 发送端接收回复的数据,再退出

接收端A:

import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.SocketException;public class UDPReceiverA {    public static void main(String[] args) throws IOException {        //1. 创建一个DatagramSocket 对象,准备在9999接收数据        DatagramSocket socket = new DatagramSocket(9999);        //2. 构建一个DatagramPacket 对象,准备接收数据        //2.1 一个数据包最大是 64k        byte[] buf = new byte[1024];        DatagramPacket packet = new DatagramPacket(buf, buf.length);        //3. 调用接收方法,将通过网络传输的 DatagramPacket 对象        //填充到packet对象        //注意:当有数据包发送到 本机的9999端口,就会接收到数据        //如果没有数据包发送到,本机的9999端口,就会堵塞等待        System.out.println("接收端A 等待接收数据...");        socket.receive(packet);        //4. 可以把packet进行一个拆包,取出数据,并显示        int length = packet.getLength();//实际接收到的数据长度        byte[] data = packet.getData();//接收到数据        String s = new String(data, 0, length);        System.out.println(s);        //--------回复信息----------        //将需要发送的数据,封装到DatagramPacket对象       data = "A:好的,没有问题".getBytes();        //说明: 封装的 DatagramPacket对象 (内容字节数组, data.length, 主机ip, d端口)        DatagramPacket datagramPacket =                new DatagramPacket(data, data.length, InetAddress.getByName("192.168.131.1"), 9998);        socket.send(datagramPacket);        //5. 关闭资源        socket.close();        System.out.println("A端退出");    }}

发送端B:

import java.io.IOException;import java.net.*;public class UDPSenderB {    public static void main(String[] args) throws IOException {        //1. 创建 DatagramSocket对象,准备在 9998接收数据        DatagramSocket datagramSocket = new DatagramSocket(9998);        //2. 将需要发送的数据,封装到DatagramPacket对象        byte[] data = "B:hello,明天吃火锅".getBytes();        //3. 说明: 封装的 DatagramPacket对象 (内容字节数组, data.length, 主机ip, d端口)        DatagramPacket datagramPacket =                new DatagramPacket(data, data.length, InetAddress.getByName("192.168.131.1"), 9999);        datagramSocket.send(datagramPacket);        //---------接受从A端回复的信息-----------        byte[] bytes = new byte[1024];        DatagramPacket datagramPacket1 = new DatagramPacket(bytes, bytes.length);        datagramSocket.receive(datagramPacket1);        int length = datagramPacket1.getLength();        byte[] data1 = datagramPacket1.getData();        String s = new String(data1, 0, length);        System.out.println(s);        //4. 关闭资源        datagramSocket.close();        System.out.println("B端退出");    }}

上一篇:轻松下载hoho应用,一步步带你掌握方法!

下一篇:美国服务器国内哪里跳板?