android基于UDP实现聊天小功能

一、DatagramSocket

DatagramSocket 是 Java 中用于发送和接收 UDP 数据包的类。它提供了创建和管理 UDP 套接字的功能。以下是 DatagramSocket 类的一些常用方法:

  • DatagramSocket(): 创建一个未绑定到特定本地地址和端口的 DatagramSocket 实例。

  • DatagramSocket(int port): 创建一个绑定到指定本地端口的 DatagramSocket 实例。

  • void send(DatagramPacket packet): 发送一个数据包到目标地址。

  • void receive(DatagramPacket packet): 接收一个数据包。

  • void bind(SocketAddress address): 将套接字绑定到指定的本地地址。

  • void close(): 关闭套接字。

二、DatagramPacket

DatagramPacket 是 Java 中用于表示 UDP 数据包的类。它包含了数据包的内容、目标地址和端口等相关信息。以下是 DatagramPacket 类的一些常用方法:

  • DatagramPacket(byte[] data, int length): 创建一个接收数据包的实例,使用指定的字节数组和数据长度。

  • DatagramPacket(byte[] data, int length, InetAddress address, int port): 创建一个发送数据包的实例,使用指定的字节数组、数据长度、目标地址和目标端口。

  • byte[] getData(): 获取接收到的数据包的字节数组。

  • void setData(byte[] data): 设置要发送的数据包的字节数组。

  • int getLength(): 获取数据包的长度。

  • void setLength(int length): 设置数据包的长度。

  • InetAddress getAddress(): 获取数据包的目标地址。

  • void setAddress(InetAddress address): 设置数据包的目标地址。

  • int getPort(): 获取数据包的目标端口。

  • void setPort(int port): 设置数据包的目标端口。

三、核心代码

3.1、接收UDP数据线程MyReceiveThread

private class MyReceiveThread implements Runnable {
        @Override
        public void run() {
            //要循环接收数据
            while (true) {
                try {
                    Log.d(TAG, "udp waiting....");
                    receivedSocket.receive(packet);
                    //获取数据的时候,要使用带有offset的
                    String msg = new String(packet.getData(), 0, packet.getLength(), "UTF-8");
                    Log.e(TAG, "Received msg:" + msg);
                    targetIp = packet.getAddress().getHostAddress();
                    MessageEntity messageEntity = new MessageEntity();
                    messageEntity.setRole(MessageEntity.ROLE_CLIENT);
                    messageEntity.setMessage(msg);
                    mEntities.add(messageEntity);
                    etTargetIp.post(() -> mMessageAdapter.notifyDataSetChanged());
                } catch (SocketException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    receivedSocket.close();
                }
            }
        }
    }
  • 接收数据的时候,要开启一个循环
  • 获取数据的时候,要使用String(byte bytes[], int offset, int length, String charsetName)

3.2、发送数据

public void sendMsg(View view) {
        targetIp = etTargetIp.getText().toString();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    DatagramSocket socket = new DatagramSocket();
                    String message = msg.getText().toString();
                    byte[] msgs = message.getBytes("UTF-8");
                    InetAddress address = InetAddress.getByName(targetIp);
                    DatagramPacket packet = new DatagramPacket(msgs, msgs.length);
                    packet.setAddress(address);
                    packet.setPort(PORT);
                    socket.send(packet);
                    MessageEntity messageEntity = new MessageEntity();
                    messageEntity.setRole(MessageEntity.ROLE_HOST);
                    messageEntity.setMessage(message);
                    mEntities.add(messageEntity);
                    etTargetIp.post(() -> mMessageAdapter.notifyDataSetChanged());
                } catch (SocketException e) {
                    e.printStackTrace();
                    Log.e(TAG, e.getMessage());
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                    Log.e(TAG, e.getMessage());
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e(TAG, e.getMessage());
                }
            }
        }).start();
    }

Github

四、使用tcpdump抓包

4.1、tcpdump官网下载

android基于UDP实现聊天小功能_第1张图片

4.2、adb push

adb push D:\tcpdump /data/

4.3、给tcpdump执行权限

adb shell
cd data
chmod +x tcpdump

4.3、查看设备的网口

./tcpdump -D 

android基于UDP实现聊天小功能_第2张图片

4.4、抓取wlan0的数据包

./tcpdump -i wlan0 -w 2.pcap

在这里插入图片描述
android基于UDP实现聊天小功能_第3张图片

4.5、导出抓包数据

adb pull /data/2.pcap D:\

4.6、使用wireshark打开2.pcap文件

android基于UDP实现聊天小功能_第4张图片

五、网络协议

android基于UDP实现聊天小功能_第5张图片

上面是一条完整的UDP数据包

5.1、以太网(Ethernet)

android基于UDP实现聊天小功能_第6张图片

以太网(Ethernet)是一种常用的有线局域网(LAN)技术,用于在计算机和其他网络设备之间进行数据通信。它定义了物理层和数据链路层的规范,用于在局域网中传输数据帧。

以太网使用数据链路层协议来组织和管理数据的传输。最常见的以太网数据链路层协议是**以太网帧(Ethernet Frame)**格式,它定义了数据帧的结构和字段。以太网帧包括源和目标MAC地址、帧类型、数据、校验和等字段。

5.1.1、以太网首部结构

android基于UDP实现聊天小功能_第7张图片

  • 以太网首部的长度为14个字节
  • 以太网首部的字段包括:
    • 目标MAC地址(Destination MAC Address)6个字节:指示帧的目标设备的MAC地址,用于将帧发送到正确的目标设备。
      android基于UDP实现聊天小功能_第8张图片

    • 源MAC地址(Source MAC Address)6个字节:指示帧的发送方设备的MAC地址,用于标识帧的来源。
      android基于UDP实现聊天小功能_第9张图片

    • 以太网类型(Ethernet Type)或长度(Length)2个字节:指示帧中包含的上层协议类型或数据部分长度。以太网类型字段通常用于标识上层协议,如IPv4(值为0x0800)IPv6(值为0x86DD)ARP(值为0x0806) 等。长度字段在某些情况下用于指示数据部分的长度。
      android基于UDP实现聊天小功能_第10张图片

5.2、IP协议

在这里插入图片描述
IP(Internet Protocol)协议是互联网中最核心的网络协议之一,它负责在网络中传输数据包。IP协议定义了数据包的格式、路由选择和分组交换等机制,使得数据能够在不同的网络之间进行传输和路由。

以下是IP协议的主要特点和功能:
1、 无连接性:IP协议是一种无连接的协议,每个IP数据包都是独立传输的。在发送数据时,每个数据包被独立处理,并根据目标地址进行路由选择。这种无连接性使得IP协议的传输效率较高,但也意味着它不提供可靠性保证,不保证数据包的顺序和可靠传输。

2、数据包格式:IP协议定义了数据包的格式,通常称为IP数据报(IP Datagram)。IP数据报由首部(Header)和有效载荷(Payload)组成。IP首部包含了源IP地址、目标IP地址、协议版本、首部长度、服务类型、数据包长度、标识、生存时间(TTL)、校验和等字段,用于控制和识别数据包。有效载荷部分包含上层协议的数据。

3、IP地址:IP协议使用IP地址来标识网络中的设备。IP地址是一个32位(IPv4)或128位(IPv6)的数字标识符。IPv4地址由四个8位的数字组成,每个数字用点分隔。IPv6地址通常使用八组四位的十六进制数表示。IP地址用于寻址和路由选择,确保数据包能够正确到达目标设备。

4、路由选择:IP协议使用路由选择算法将数据包从源主机传输到目标主机。路由选择根据目标IP地址和路由表中的路由信息进行决策,确定下一跳的路径。路由选择算法的目标是找到最佳路径,使数据包能够以最高效的方式到达目标设备。

5、分组交换:IP协议采用分组交换的方式传输数据包。数据包在发送端被分成较小的数据块(分组),每个分组独立传输。在网络中,每个分组根据目标地址进行独立的路由选择和转发,最终在目标设备上重新组装成完整的数据包。这种分组交换的方式提高了网络的利用率和灵活性。

6、差错检测:IP协议使用校验和字段对数据包进行差错检测。发送端在发送数据包时计算校验和,并将其包含在IP首部中。接收端在接收到数据包后,重新计算校验和,并与接收到的校验和进行比较,以检测数据包是否在传输过程中发生了错误。

5.2.1、IP数据报首部

android基于UDP实现聊天小功能_第11张图片
android基于UDP实现聊天小功能_第12张图片
IPv4首部字段(20字节)

  • 版本(Version):占4位,指定IP协议的版本号,IPv4为4。
    android基于UDP实现聊天小功能_第13张图片

  • 首部长度(Header Length):占4位,指定IP首部的长度,以4字节为单位。由于IPv4首部长度最多为15个4字节(60字节),因此它实际上是首部中32位字的数量。
    android基于UDP实现聊天小功能_第14张图片
    android基于UDP实现聊天小功能_第15张图片
    16进制45的二进制为0100 0101,其中前4位代表IP协议的version,后4位代表IP协议首部长度

  • 服务类型(Type of Service):占8位,用于指定数据包的服务质量要求,如优先级、延迟和吞吐量等。
    android基于UDP实现聊天小功能_第16张图片

  • 总长度(Total Length):占16位,指定整个IP数据包的长度,包括首部和数据部分。
    android基于UDP实现聊天小功能_第17张图片

  • 标识(Identification):占16位,用于标识数据包的唯一性,通常由发送端设置,并在接收端进行处理。
    android基于UDP实现聊天小功能_第18张图片

  • 标志(Flags):占3位,用于指示数据包的特殊处理标志。其中包括禁止分片标志(DF)和更多分片标志(MF)。
    android基于UDP实现聊天小功能_第19张图片

  • 片偏移(Fragment Offset):占13位,用于指定数据包片段在原始数据包中的位置。
    android基于UDP实现聊天小功能_第20张图片

  • 生存时间(Time to Live,TTL):占8位,表示数据包在网络中可以经过的最大路由跳数。每经过一个路由器,该字段的值减1,当值为0时,数据包将被丢弃。
    android基于UDP实现聊天小功能_第21张图片

  • 协议(Protocol):占8位,指定上层协议类型,如TCP、UDP或ICMP。
    android基于UDP实现聊天小功能_第22张图片

  • 首部校验和(Header Checksum):占16位,用于校验IP首部的完整性。
    android基于UDP实现聊天小功能_第23张图片

  • 源IP地址(Source IP Address):占32位,指定数据包的源IP地址。
    android基于UDP实现聊天小功能_第24张图片

  • 目标IP地址(Destination IP Address):占32位,指定数据包的目标IP地址。
    android基于UDP实现聊天小功能_第25张图片

5.3、UDP协议

在这里插入图片描述
UDP(User Datagram Protocol)是一种面向无连接传输层协议。与TCP(Transmission Control Protocol)相比,UDP更加轻量级,没有建立和维护连接的开销,因此传输效率更高,但也不提供可靠性保证。

以下是UDP的主要特点和用途:

  • 无连接性:UDP是一种无连接的协议,不需要在发送数据之前建立连接。每个UDP数据包都是独立发送的,不会进行握手和确认。这使得UDP的传输速度较快,适用于实时性要求较高的应用。

  • 简单性与轻量性:相比TCP,UDP的协议头部较小,仅包含源端口、目标端口、长度和校验和等简单字段。这使得UDP的开销较小,传输效率较高。

  • 不可靠性:UDP不提供数据包的可靠性保证。它不保证数据包的顺序和可靠传输,也不进行重传和拥塞控制。因此,如果使用UDP进行数据传输,必须由应用层自行处理数据的完整性和可靠性。

  • 广播和多播支持:UDP支持广播和多播传输。通过UDP广播,可以将数据包发送到同一网络中的所有主机。而通过UDP多播,可以将数据包发送到特定的多播组。

  • 实时性要求:由于UDP的无连接性和较低的开销,它在实时性要求较高的应用中得到广泛应用。例如,音频和视频流传输、实时游戏和语音通信等。

  • 域名解析:UDP常用于域名解析中的DNS(Domain Name System)服务。DNS使用UDP协议在域名服务器和客户端之间进行域名解析查询和响应。

5.3.1、UDP首部

android基于UDP实现聊天小功能_第26张图片
UDP(User Datagram Protocol)的首部(Header)是UDP数据报中用于控制和识别的固定长度字段集合。UDP首部包含以下字段:

  • 源端口号(Source Port):占16位,指定发送方的端口号。
    android基于UDP实现聊天小功能_第27张图片

  • 目标端口号(Destination Port):占16位,指定接收方的端口号。
    android基于UDP实现聊天小功能_第28张图片

  • 长度(Length):占16位,指定UDP数据报的总长度(包括首部和数据部分)。
    android基于UDP实现聊天小功能_第29张图片

  • 校验和(Checksum):占16位,用于校验UDP数据报的完整性。
    android基于UDP实现聊天小功能_第30张图片

5.4、ARP协议数据包

ARP(Address Resolution Protocol)是一种用于将IP地址映射到物理MAC地址的协议。它在TCP/IP网络中起着重要的作用,用于解决主机在发送数据时,如何根据目标IP地址找到对应的物理MAC地址的问题。

以下是ARP协议的基本工作原理:

  • ARP请求:当主机需要向目标IP地址发送数据时,首先检查本地的ARP缓存(ARP Cache)中是否存在目标IP地址对应的MAC地址。如果缓存中没有对应的映射关系,主机会发送一个ARP请求广播到本地网络中的所有主机。

  • ARP应答:接收到ARP请求的主机,如果发现自己的IP地址与请求中的目标IP地址匹配,就会发送一个ARP应答给请求方,包含自己的MAC地址。

  • ARP缓存更新:请求方收到ARP应答后,会将目标IP地址与对应的MAC地址的映射关系存储在本地的ARP缓存中,以便将来使用。这样,当再次需要向目标IP地址发送数据时,就可以直接从ARP缓存中获取目标的MAC地址。

ARP协议使用的是广播的方式,因此ARP请求和应答都会发送到本地网络中的所有主机。只有与请求IP地址匹配的主机才会应答,其他主机会忽略。

ARP协议的作用是解决逻辑地址(IP地址)到物理地址(MAC地址)的映射问题,使数据能够正确地在网络中传输。它在局域网中起着重要的作用,帮助主机建立和维护IP地址与MAC地址之间的映射关系。

5.4.1、ARP协议的首部

android基于UDP实现聊天小功能_第31张图片
ARP(Address Resolution Protocol)协议的首部(Header)包含以下字段:

  • 硬件类型(Hardware Type):占2个字节,指定网络硬件类型,如以太网、无线局域网等。常见的以太网类型为1。
    android基于UDP实现聊天小功能_第32张图片

  • 协议类型(Protocol Type):占2个字节,指定网络层协议类型,通常为IPv4或IPv6。IPv4的协议类型为0x0800。
    android基于UDP实现聊天小功能_第33张图片

  • 硬件地址长度(Hardware Address Length):占1个字节,指定硬件地址的长度,通常为6个字节(以太网MAC地址长度)。
    android基于UDP实现聊天小功能_第34张图片

  • 协议地址长度(Protocol Address Length):占1个字节,指定协议地址的长度,通常为4个字节(IPv4地址长度)。
    android基于UDP实现聊天小功能_第35张图片

  • 操作码(Operation Code):占2个字节,指定ARP消息的类型。常见的操作码包括请求(1)和应答(2)。
    android基于UDP实现聊天小功能_第36张图片
    android基于UDP实现聊天小功能_第37张图片

  • 发送方硬件地址(Sender Hardware Address):占长度与硬件地址长度字段指定的长度相同,指定发送方的硬件地址,即发送方的MAC地址。
    android基于UDP实现聊天小功能_第38张图片

  • 发送方协议地址(Sender Protocol Address):占长度与协议地址长度字段指定的长度相同,指定发送方的协议地址,即发送方的IP地址。
    android基于UDP实现聊天小功能_第39张图片

  • 目标硬件地址(Target Hardware Address):占长度与硬件地址长度字段指定的长度相同,指定目标的硬件地址,即目标的MAC地址。
    android基于UDP实现聊天小功能_第40张图片
    因为目前还不知道对方的Mac地址,所以此时为0

  • 目标协议地址(Target Protocol Address):占长度与协议地址长度字段指定的长度相同,指定目标的协议地址,即目标的IP地址。
    android基于UDP实现聊天小功能_第41张图片

ARP协议首部的长度固定为28个字节(224位)

使用ARP协议,主机可以通过发送ARP请求来查询目标IP地址对应的MAC地址。接收到ARP请求的主机会发送ARP应答,将自己的MAC地址告知请求方。这样,发送方就能够获得目标IP地址与对应的MAC地址的映射关系,并在数据传输时使用正确的MAC地址。

需要注意的是,ARP协议在广播域内工作,即只适用于同一局域网内的主机之间。在跨网段通信时,会使用其他协议(如ARP的扩展协议Proxy ARP、ARP的替代协议NDP等)来解决IP地址到MAC地址的映射问题。

始终牢记一个原则:只要是在网络上跑的包,都是完整的。可以有下层没上层,绝对不可能有上层没下层。

你可能感兴趣的:(网络协议,Android基础,UDP,网络协议)