• 网络编程入门


    目录

    一、网络编程入门

    1.软件结构

    2.网络通信协议

    ​编辑 3.协议分类

    4.网络编程要素 

    IP地址

    IP地址分类

    常用命令

     特殊的IP地址

    InetAddress 类 

    常用方法

    端口号 

    二、UDP协议编程

    DatagramSocket类

    构造方法

    常用方法 

    DatagramPacket类 

    构造方法

    常用方法 

    使用UDP通信 

    UDP三种通讯方式

    UDP组播实现

     UDP广播实现

     三、TCP通信程序

    Socket 类

    构造方法


    一、网络编程入门

    1.软件结构

    C/S结构:全称为Client/Server结构,是指客户端和服务端结构。常见程序有QQ、迅雷等软件。

    B/S结构:全程为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。

     两种架构各有优势,但是无论哪种架构,都离不开网络的支持。网络编程,就是在一定的
    协议下,实现两台计算机的通信的程序。

    2.网络通信协议

    通信协议是对计算计必须遵守的规则,只有遵守这些规则,计算机之间才能进行通信。这
    就好比在道路中行驶的汽车一定要遵守交通规则一样,协议中对数据的传输格式、传输速
    率、传输步骤等做了统一规定,通信双方必须同时遵守,最终完成数据交换。

    • TCP/IP协议:传输控制协议/因特网互联协议,是Internet最基本、最广泛的协议。它定义了计算机如何连入因特网,以及数据如何在它们之间传输的标准。它的内部包含一系列的用于处理通信的协议,并采用了四层的分层模型,每一层都呼叫他的下一层所提供的协议来完成自己的需求。

     3.协议分类

    通信的协议还是比较复杂的,java.net包中的类和接口,他们提供低层次的通信细节。我们可以直接使用这些类和接口,来专注于网络程序开发,而不用考虑通信的细节。

    java.nei包中提供两种常见的网络协议的支持:

    • TCP:传输控制协议。TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。
    • 三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务端之间的三次交互,以保证连接的可靠。
    • 第一次握手,客户端向服务器端发出连接请求,等待服务器确认。
    • 第二次握手,服务端向客户端回送一个响应,通知客户端受到了连接请求。
    • 第三次握手,客户端再次向服务器端发送确认信息,确认连接。

    完成三次握手,建立连接后,客户端和服务器就可以开始进行数据传输了。由于这种面向
    连接的特性,TCP协议可以保证传输数据的安全,所以应用十分广泛,例如下载文件、浏
    览网页等。

    • UDP:用户数据报协议。UDP协议是一个面向无连接的协议。 传输数据时,不需要建立连接,不管对方端服务是否启动,直接将数据、数据源和目的地分装在数据包中,直接发送。它是不可靠协议,因为无连接,所以传输速度快,但是容易丢失数据。

    补充:三次握手和四次挥手

    建立连接(三次握手):

     断开连接(四次挥手):

    4.网络编程要素 

    协议、IP地址、端口号。

    IP地址

    互联网协议地址,俗称IP。IP地址用来给一个网络中的计算机设备做唯一的编号。假如我们把“个人电脑”比作“一台电话”的话,那么“IP地址”就相当于“电话号码”。

    IP地址分类

    IPv4:是一个32位的二进制数,通常被分为四个字节,表示为a.b.c.d的形式,例如192.168.1.66。其中a、b、c、d都是0~255之间的十进制整数,那么最多可以表示42亿个。

    IPv6:为了互联网的蓬勃发展,IP地址的需求量越来越大,但是网络地址资源有限,使得IP的分配愈发紧张。有资料显示,全球IPv4地址在2011年2月分配完毕。为了扩大地址空间,拟通过IPv6重新定义地址空间,采用128位地址长度,每16个字节一组,分成8组十六进制数,表示成 ABCD:EF01:2345:6789:ABCD:EF01:2345:6789 ,号称可以为全世界的每一粒沙子编上一个网址,这样就解决了网络地址资源数量不够的问题。

    常用命令
    • 查看本机IP地址,在控制台输入
    ipconfi
    •  检查网络是否连通,在控制台输入 
    ping 空格 IP地址
     特殊的IP地址
    • 127.0.0.1 / localhost 都表示本机

    区别:

    1. localhost 等于 127.0.0.1 ,不过 localhost 是域名, 127.0.0.1 是 IP 地址。 

    2. localhost 和 127.0.0.1 不需要联网,都是本机访问

    3. 本机 IP 需要联网,本机 IP 是本机或外部访问, 本机 IP 就是本机对外放开访问的 I
    P 地址,这个网址就是与物理网卡绑定的 IP 地址
    4. localhost 是一个域名,在过去它指向 127.0.0.1 这个IP地址。在操作系统支持 ipv6
    后,它同时还指向ipv6 的地址 ::1

    InetAddress 类 

    java.net.InetAddress 表示Internet协议( IP )地址。 IP 地址是由 IP 使用的32位或
    128位无符号数字,构建 UDP 和 TCP 协议的低级协议。

    常用方法
    • public static InetAddress[] getAllByName(String host) 给定主机的名称,根据系统上配置的名称服务返回其 IP 地址数组
    • public static InetAddress getByName(String host) 确定主机名称的 IP 地址。
    • public static InetAddress getLocalHost() 返回本地主机的地址
    • public String getHostAddress() 返回文本显示中的 IP 地址字符串
    端口号 

    网络的通信,本质上是两个进程(应用程序)的通信。每台计算机都有很多的进程,那么
    在网络通信时,如何区分这些进程呢?

    如果说 IP 地址可以唯一标识网络中的设备,那么端口号就可以唯一标识设备中的进程
    (应用程序)了。每个端口同时只能有一个进程使用,端口是计算机与外界通信的入口和
    出口。

    端口号:用两个字节表示的整数,它的取值范围是 0~65535 。其中, 0~1023 之间的端口
    号用于一些知名的网络服务和应用,普通的应用程序需要使用 1024 以上的端口号。如果
    端口号被另外一个服务或应用所占用,会导致当前程序启动失败。

    利用 协议 + IP地址 + 端口号 三元组合,就可以标识网络中的进程了,那么进程间的通
    信就可以利用这个标识与其它进程进行交互。

    查看本机端口情况使用 netstat -ano 命令

    telnet ip 端口

    二、UDP协议编程

    DatagramSocket类

    java.net.DatagramSocket 表示用于发送和接收数据报数据包的套接字,数据报套接字是分
    组传送服务的发送或接收点。 DatagramSocket 应该绑定到通配符地址。 在一些实现中,
    当 DatagramSocket 绑定到更具体的地址时,也可以接收广播分组。

    构造方法

    常用构造方法有:

    • public DatagramSocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定
      端口。
    • public DatagramSocket(int port, InetAddress laddr) 创建一个数据报套接字,绑定
      到指定的本地地址。
    常用方法 
    • public void send(DatagramPacket p) 从此套接字发送数据报包。 DatagramPacket 包括指示要发送的数据,其长度,远程主机的 IP 地址和远程主机上的端口号的信息。
    • public synchronized void receive(DatagramPacket p) 从此套接字接收数据报包。

    当此方法返回时, DatagramPacket 的缓冲区将填充接收到的数据。 数据包数据包还包
    含发送者的 IP 地址和发件人机器上的端口号。 该方法阻塞,直到接收到数据报。 数
    据报包对象的length字段包含接收到的消息的长度。 如果消息长于数据包的长度,消息
    将被截断。 

    DatagramPacket类 

    java.net.DatagramPacket 表示数据报包,数据报包用于实现无连接分组传送服务。 仅基于
    该数据包中包含的信息,每个消息从一台机器路由到另一台机器。

    构造方法
    • public DatagramPacket(byte buf[], int offset, int length, InetAddress address,
      int port) 构造用于发送长度的分组的数据报包 ,length,指定主机上到指定的端口号。
    • public DatagramPacket(byte buf[], int length) 构造一个 DatagramPacket 用于接
      收长度的数据包 length
    常用方法 
    • public synchronized int getLength() 返回要发送的数据的长度或接收到的数据的长
    • public synchronized InetAddress getAddress() 返回该数据报发送或接收数据报的计
      算机的 IP 地址。
    • public synchronized byte[] getData() 返回数据缓冲区

    使用UDP通信 

    步骤:

    1. 【发送端】 创建目标主机发送对象 DatagramSocket

    2. 【发送端】 创建发送信息 DatagramPacket 对象

    3. 【发送端】 发送端发送信息

    4. 【接收端】 创建用于接收信息的 DatagramPacket 对象

    5. 【接收端】 创建 DatagramSocket 对象

    6. 【接收端】 接收信息

    发送端

    1. package network.day3;
    2. import java.io.IOException;
    3. import java.net.*;
    4. /**
    5. * 练习:
    6. * 发送端:发送数据来源于键盘录入,直到输入 end 表示发送结束
    7. * 发送端要写一个专门接收响应的线程,用于接收对方的反馈接收端:死循环接收数据
    8. * 接收端接收到数据后,向发送端指定端口发送一条 接收到信息的反馈
    9. * 发送端发送消息时包含以下部分:
    10. * 1.消息格式(text, mp3,jpg, png,..
    11. * 2.消息内容
    12. * 3.发送时间
    13. * 4.接收回复端口
    14. * 建议包装成jison
    15. */
    16. public class SendDemo {
    17. public static void main(String[] args) {
    18. try {
    19. //发送数据报
    20. DatagramSocket socket = new DatagramSocket();
    21. InetAddress localHost = InetAddress.getByName("WIN-EB2ASK9538P");
    22. int post=8080;
    23. System.out.println(socket.getPort());
    24. System.out.println(socket.getLocalPort());
    25. String s="咕噜咕噜咕噜噜";
    26. DatagramPacket datagramPacket = new DatagramPacket(s.getBytes(), s.getBytes().length, localHost, post);
    27. socket.send(datagramPacket);
    28. System.out.println("发送成功");
    29. socket.close();
    30. } catch (SocketException e) {
    31. throw new RuntimeException(e);
    32. } catch (UnknownHostException e) {
    33. throw new RuntimeException(e);
    34. } catch (IOException e) {
    35. throw new RuntimeException(e);
    36. }
    37. }
    38. }

    接收端

    1. package network.day3;
    2. import java.io.IOException;
    3. import java.net.DatagramPacket;
    4. import java.net.DatagramSocket;
    5. import java.net.SocketException;
    6. /**
    7. * 使用UDP协议接收数据
    8. */
    9. public class UDPReceive {
    10. public static void main(String[] args) {
    11. //存储接收到的数据
    12. byte[] bytes = new byte[1024];
    13. DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
    14. try {
    15. DatagramSocket socket = new DatagramSocket(8080);
    16. socket.receive(datagramPacket);
    17. String s = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
    18. System.out.println(datagramPacket.getAddress()+"发送了:"+s);
    19. } catch (SocketException e) {
    20. throw new RuntimeException(e);
    21. } catch (IOException e) {
    22. throw new RuntimeException(e);
    23. }
    24. }
    25. }
    UDP三种通讯方式
    • 单播

    单播用于两个主机之间的端对端通信

    • 组播

    组播用于对一组特定的主机进行通信

    • 广播

    广播用于一个主机对整个局域网上所有主机上的数据通信

    UDP组播实现

    组播地址: 224.0.0.0 ~ 239.255.255.255

    其中 224.0.0.0 ~ 224.0.0.255 为预留的组播地址

    • 实现步骤
    • 发送端

    1. 创建发送端的Socket对象(DatagramSocket)

    2. 创建数据,并把数据打包(DatagramPacket)
    3. 调用DatagramSocket对象的方法发送数据(在单播中,这里是发给指定IP的电脑但
    是在组播当中,这里是发给组播地址)
    4. 释放资源

    • 接收端

    1. 创建接收端Socket对象(MulticastSocket)
    2. 创建一个箱子,用于接收数据
    3. 把当前计算机绑定一个组播地址
    4. 将数据接收到箱子中
    5. 解析数据包,并打印数据
    6. 释放资源

    1. // 发送端
    2. public class ClinetDemo {
    3. public static void main(String[] args) throws IOException {
    4. // 1. 创建发送端的Socket对象(DatagramSocket)
    5. DatagramSocket ds = new DatagramSocket();
    6. String s = "hello 组播";
    7. byte[] bytes = s.getBytes();
    8. InetAddress address = InetAddress.getByName("224.0.1.0");
    9. int port = 10000;
    10. // 2. 创建数据,并把数据打包(DatagramPacket)
    11. DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);
    12. // 3. 调用DatagramSocket对象的方法发送数据(在单播中,这里是发给指定IP的电脑但是
    13. 在组播当中,这里是发给组播地址)
    14. ds.send(dp);
    15. // 4. 释放资源
    16. ds.close();
    17. }
    18. }
    19. // 接收端
    20. public class ServerDemo {
    21. public static void main(String[] args) throws IOException {
    22. // 1. 创建接收端Socket对象(MulticastSocket)
    23. MulticastSocket ms = new MulticastSocket(10000);
    24. // 2. 创建一个箱子,用于接收数据
    25. DatagramPacket dp = new DatagramPacket(new byte[1024],1024);
    26. // 3. 把当前计算机绑定一个组播地址,表示添加到这一组中.
    27. ms.joinGroup(InetAddress.getByName("224.0.1.0"));
    28. // 4. 将数据接收到箱子中
    29. ms.receive(dp);
    30. // 5. 解析数据包,并打印数据
    31. byte[] data = dp.getData();
    32. int length = dp.getLength();
    33. System.out.println(new String(data,0,length));
    34. // 6. 释放资源
    35. ms.close();
    36. }
    37. }
     UDP广播实现

    广播地址: 255.255.255.255

    当数据发送到广播地址时,会把数据发送给所有能连接的计算机

    • 实现步骤
    • 发送端
    1. 创建发送端Socket对象(DatagramSocket)
    2. 创建存储数据的箱子,将广播地址封装进去
    3. 发送数据
    4. 释放资源 
    • 接收端 
    1. 创建接收端的Socket对象(DatagramSocket)
    2. 创建一个数据包,用于接收数据
    3. 调用DatagramSocket对象的方法接收数据
    4. 解析数据包,并把数据在控制台显示
    5. 关闭接收端 
    1. // 发送端
    2. public class ClientDemo {
    3. public static void main(String[] args) throws IOException {
    4. // 1. 创建发送端Socket对象(DatagramSocket)
    5. DatagramSocket ds = new DatagramSocket();
    6. // 2. 创建存储数据的箱子,将广播地址封装进去
    7. String s = "广播 hello";
    8. byte[] bytes = s.getBytes();
    9. InetAddress address = InetAddress.getByName("255.255.255.255");
    10. int port = 10000;
    11. DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);
    12. // 3. 发送数据
    13. ds.send(dp);
    14. // 4. 释放资源
    15. ds.close();
    16. }
    17. }
    18. // 接收端
    19. public class ServerDemo {
    20. public static void main(String[] args) throws IOException {
    21. // 1. 创建接收端的Socket对象(DatagramSocket)
    22. DatagramSocket ds = new DatagramSocket(10000);
    23. // 2. 创建一个数据包,用于接收数据
    24. DatagramPacket dp = new DatagramPacket(new byte[1024],1024);
    25. // 3. 调用DatagramSocket对象的方法接收数据
    26. ds.receive(dp);
    27. // 4. 解析数据包,并把数据在控制台显示
    28. byte[] data = dp.getData();
    29. int length = dp.getLength();
    30. System.out.println(new String(data,0,length));
    31. // 5. 关闭接收端
    32. ds.close();
    33. }
    34. }

     三、TCP通信程序

    TCP通信能实现两台计算机之间的数据交互,通信的两端,要严格区分为客户端(Client)
    与服务端(Server)。

    Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,
    并通过Socket产生IO流来进行网络通信。

    Java为客户端提供了Socket类,为服务器端提供了ServerSocket类。

    两端通信时步骤:

    1. 服务端程序,需要事先启动,等待客户端的连接。
    2. 客户端主动连接服务器端,连接成功才能通信。服务端不可以主动连接客户端。
      在 Java 中,提供了两个类用于实现 TCP 通信程序:

                  1.客户端: java.net.Socket 类表示。创建 Socket 对象,向服务端发出连接请
    求,服务端响应请求,两者建立连接开始通信。

                 2.服务端: java.net.ServerSocket 类表示。创建 ServerSocket 对象,相当于开启
    一个服务,并等待客户端的连接。

    Socket 类

    Socket 类 :该类实现客户端套接字,套接字指的是两台设备之间通讯的端点。

    public class Socket implements java.io.Closeable
    构造方法

    常用的构造方法是:

    1. //创建流套接字并将其连接到指定主机上的指定端口号,如果指定的主机是null ,则相当于指定地址为
    2. InetAddress.getByName (null) 。 换句话说,它相当于指定回送接口的地址
    3. public Socket(String host, int port)

    回送地址(127.x.x.x) 是本机回送地址(Loopback Address),主要用于网络软件测试
    以及本地机进程间通信,无论什么程序,一旦使用回送地址发送数据,立即返回,不
    进行任何网络传输。

  • 相关阅读:
    如何让 Docker Compose 等待依赖容器
    【redis】redis持久化学习
    当当API关键字搜索接口技术:实现快速商品搜索与推荐
    什么是族?全面带你了解Revit族基本知识
    【简单】 猿人学web第一届 第3题 罗生门
    MySQL 查询 - 排除某些字段的SQL查询,提升查询性能
    react中受控组件与非受控组件
    高斯消元
    宝塔自建bitwarden密码管理器
    【云原生】Docker可视化监控管理工具使用
  • 原文地址:https://blog.csdn.net/m0_57229804/article/details/133102951