初始网络编程

什么是网络编程

在网络通信协议下,不同计算机上运行的程序,进行的数据传输

应用场景

不管是什么场景,都是计算机跟计算机之间通过网络进行数据传输

  • Java中可以使用java.net包下的技术轻松来发出常见的网络应用程序

常见的软件架构

二者区别和优缺点

C/S: Client/Server 客户端/服务端(用户要在本地安装一个客户端程序,远程要有一个服务器端程序)(客户端+服务器)(一切的一切都在服务器,都要靠网络传输)

B/S Browser/Server 浏览器/服务器(只用浏览器,根据网址,访问不同的服务器)(浏览器+服务器)(例如:游戏的音乐、画面等都在安装包里,服务器只用告诉浏览器该怎么做就行)

不管是客户端还是浏览器,都只是负责将程序展示出来。

真正的核心逻辑都在服务器当中。

网络编程三要素

确定对方电脑在互联网上的地址:IP

确定接收数据的软件:端口号

确定网络传输的规则:协议

  • IP
    • 设备在网络中的地址,是唯一的标识
  • 端口号
    • 应用程序在设备中唯一的标识
  • 协议
    • 数据在网络中传输的规则,常见的协议有UDP,TCP,http,https,ftp

1. IP

全称:Internet Protocol 互联网协议地址,也称IP地址

是分配给上网设备的数字标签

常见的IP分类 IPv4 IPv6

IPv4

i p version4,互联网通信协议第四版

32位地址长度,分成4组

32bit(4字节)

二进制阅读不方便,就点分十进制表示,例192.168.1.66

有限

IPv6

128bit 8组 1组2字节

还没有大规模使用

IPv4的一些细节

IPv4的地址分类形式

  • 公网地址(万维网使用)和私有地址(局域网使用)
  • 192.168.开头的就是私有地址,专门为组织机构内部使用,以此节省IP

特殊IP地址

127.0.0.1或localhost:是回送地址,也称本地回环地址、本机IP,永远只会寻找当前所在本机

小细节:本机可以有两个IP,一个路由器给你分配的,一个127.0.0.1。当要给本机发送消息时,使用路由器分配的IP要先经过路由器,再回到本机;而使用127.0.0.1路过网卡直接就传回来了。

常用的CMD命令

  • ipconfig:查看本机IP地址
  • ping:检查网络是否连接
    • 可以写IP地址,也可以写网址,因为网址的底层逻辑也是IP

2. 端口号

  • 端口

    • 设备上应用程序的唯一标识(可以说是应用程序之间传输的出入口)
  • 端口号

    • 由两个字节表示的整数,取值范围:0~65535
    • 其中,0~1023之间的端口号用于一些知名的网络服务或应用

注意:一个端口号只能被一个应用程序使用

3. 协议

  • 协议
    • 计算机网络中,连接和通信的规则被称为网络通信协议

  • UDP协议

    • 用户数据报协议(User Datagram Protocol)

    • UDP是面向无连接通信协议

      速度快,由大小限制,一次最多发送64K,数据不安全,易丢失数据

    • 例如视频会议、语音通话、在线视频

  • TCP协议

    • 传输控制协议(Transmission Control Protocol)

    • TCP协议是面向连接的通信协议

      速度慢,没有大小限制,数据安全

    • 例如下载软件、文字聊天、发送邮件

UDP通信协议

创建发送端的DatagramSocket对象

数据打包(DatagramPacket)

发送数据

释放资源

2.1 UDP发送数据

  • Java中的UDP通信

    • UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个Socket只是发送,接收数据的对象,因此对于基于UDP协议的通信双方而言,没有所谓的客户端和服务器的概念
    • Java提供了DatagramSocket类作为基于UDP协议的Socket
  • 构造方法

    方法名 说明
    DatagramSocket() 创建数据报套接字并将其绑定到本机地址上的任何可用端口
    DatagramPacket(byte[] buf,int len,InetAddress add,int port) 创建数据包,发送长度为len的数据包到指定主机的指定端口
  • 相关方法

    方法名 说明
    void send(DatagramPacket p) 发送数据报包
    void close() 关闭数据报套接字
    void receive(DatagramPacket p) 从此套接字接受数据报包
  • 发送数据的步骤

    • 创建发送端的Socket对象(DatagramSocket)
    • 创建数据,并把数据打包
    • 调用DatagramSocket对象的方法发送数据
    • 关闭发送端
  • 代码演示

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class SendDemo {
    public static void main(String[] args) throws IOException {
    //1.创建发送端的Socket对象(DatagramSocket)
    // DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口
    DatagramSocket ds = new DatagramSocket();

    //2.创建数据,并把数据打包
    //DatagramPacket(byte[] buf, int length, InetAddress address, int port)
    //构造一个数据包,发送长度为 length的数据包到指定主机上的指定端口号。
    byte[] bys = "hello,udp,我来了".getBytes();

    DatagramPacket dp = new DatagramPacket(bys,bys.length,InetAddress.getByName("127.0.0.1"),10086);

    //3.调用DatagramSocket对象的方法发送数据
    //void send(DatagramPacket p) 从此套接字发送数据报包
    ds.send(dp);

    //4.关闭发送端
    //void close() 关闭此数据报套接字
    ds.close();
    }
    }

2.2UDP接收数据

  • 接收数据的步骤

    • 创建接收端的Socket对象(DatagramSocket)
    • 创建一个数据包,用于接收数据
    • 调用DatagramSocket对象的方法接收数据
    • 解析数据包,并把数据在控制台显示
    • 关闭接收端
  • 构造方法

    方法名 说明
    DatagramPacket(byte[] buf, int len) 创建一个DatagramPacket用于接收长度为len的数据包
  • 相关方法

    方法名 说明
    byte[] getData() 返回数据缓冲区
    int getLength() 返回要发送的数据的长度或接收的数据的长度
  • 示例代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
    //创建接收端的Socket对象(DatagramSocket)
    DatagramSocket ds = new DatagramSocket(12345);

    //创建一个数据包,用于接收数据
    byte[] bys = new byte[1024];
    DatagramPacket dp = new DatagramPacket(bys, bys.length);

    //调用DatagramSocket对象的方法接收数据
    ds.receive(dp);

    //解析数据包,并把数据在控制台显示
    System.out.println("数据是:" + new String(dp.getData(), 0, dp.getLength()));
    }
    }
    }

2.4UDP三种通讯方式

  • 单播

    单播用于两个主机之间的端对端通信(一对一)(就是之前写过的代码)

  • 组播

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

    组播地址:224.0.0.0~239.255.255.255

    其中224.0.0.0~224.0.0.255为预留的组播地址(我们能用的)

    组播中的随便一个IP地址都可以所有的组播地址

  • 广播

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

    广播地址:255.255.255.255(发送之后就可以给局域网中所有IP发送)

TCP通信协议

TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象

通信之前要保证连接已经建立

通过Socket产生IO流来进行网络通信

1. 发送和接收数据

客户端-输出流-输入流-服务器

客户端

  1. 创建客户端的Socket对象(Socket)与指定服务端连接

    Socket(String host, int port)

  2. 获取输入流,写数据

    OutputStream getOutputStream()

  3. 释放资源

    void close()

服务器

  1. 创建服务器端的Socket对象(ServerSocket)

    ServerSocket(int port)

  2. 监听客户端连接,返回一个Socket对象

    Socket accept()

  3. 获取输入流,读数据,并把数据显示在控制台

    InputStream getInputStream()

  4. 释放资源

    void close()

2. 中文乱码问题

在服务端的连接通道中获取输入流数据时

将字节流转换为字符流,最好创建一个缓冲区

3. 代码的逻辑和细节

客户端代码和服务器代码,二者每行代码之间的逻辑

创建对象

创建对象同时连接服务器—监听客户端连接

从连接通道中获取输出流—从连接通道中获取输入流 读取数据

写入数据

释放资源—释放资源

image-20240127210610766

4. TCP 三次握手 四次挥手

三次握手四次挥手的底层是网络层的ICMP协议

  • 三次握手
image-20240127210903034
  • 四次挥手

image-20240127211101375

发送数据

接收数据

UDP练习(聊天室)

TCP通信协议

发送和接收数据

中文乱码问题

代码细节

InetAddress类

InetAddress:此类表示Internet协议(IP)地址

  • 相关方法

    方法名 说明
    static InetAddress getByName(String host) 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
    String getHostName() 获取此IP地址的主机名
    String getHostAddress() 返回文本显示中的IP地址字符串
  • 代码演示

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class InetAddressDemo {
    public static void main(String[] args) throws UnknownHostException {
    //InetAddress address = InetAddress.getByName("itheima");
    InetAddress address = InetAddress.getByName("192.168.1.66");

    //public String getHostName():获取此IP地址的主机名
    String name = address.getHostName();
    //public String getHostAddress():返回文本显示中的IP地址字符串
    String ip = address.getHostAddress();

    System.out.println("主机名:" + name);
    System.out.println("IP地址:" + ip);
    }
    }