安卓:UDP通信

news2024/11/23 11:42:36

目录

一、介绍

网络通信的三要素:

(1)、IP地址:

 IPv4: 

IPv6: 

IP地址形式:

 IP常用命令:

IP地址操作类:

(2)、端口:

(3)、协议:  

UDP协议:

UDP通信的特点: 

 二、常用类及其方法

 1. DatagramSocket类

常用方法:

2. DatagramPacket 类

常用方法: 

3. InetAddress类

常用方法:

 三、udp例子

 MainActivity:

 UdpTool :

 activity_main:

权限:

运行结果:

一、介绍

        UDP(User Datagram Protocol)是一种无连接的传输协议,它在网络通信中常用于实时应用程序,例如音频、视频流传输和在线游戏。与TCP(Transmission Control Protocol)相比,UDP具有更低的开销和更高的传输速度,但不提供可靠性和错误检测功能。

网络通信的三要素:

(1)、IP地址:

        IP地址(Internet Protocol Address)是用于在网络标识定位设备一组数字。它是互联网通信所必需的基本元素之一,用于确定数据包在网络中的传输路径。

        IP地址的作用是为每个连接到互联网的设备提供一个唯一的标识符,类似于世界上每个家庭都有一个不同的地址来进行邮件投递。通过IP地址,计算机可以相互识别并建立网络通信。

   IP地址分为两部分:网络部分主机部分。网络部分标识了设备所连接的网络,而主机部分标识了网络中的具体设备。 

        IP地址由32位或128位二进制数字组成,在常见的使用中通常表示为分组的四个十进制数,例如:192.168.0.1。IPv4(Internet Protocol version 4)地址使用32位,而IPv6(Internet Protocol version 6)地址使用128位,以满足互联网设备的增长需求。

 IPv4: 

IPv6: 

IP地址形式:

  • 公网地址、和私有地址(局域网使用)
  • 192.168. 开头的就是常见的局域网地址,范围即为192.168.0.0--192.168.255.255,专门为组织机构内部使用。

 IP常用命令:

  • ipconfig:查看本机IP地址
  • ping IP地址:检查网络是否连通

特殊IP地址

  • 本机IP: 127.0.0.1或者localhost:称为回送地址也可称本地回环地址,只会寻找当前所在本机。 

IP地址操作类:

  •     InetAddress (在下面)

(2)、端口:

        端口(Port)是用于在计算机网络中标识应用程序或服务的数字。它是网络通信中的一个重要概念,用于区分不同的网络应用和服务。

        在互联网协议(IP)中,每个主机都有一个唯一的IP地址,而端口号则用于标识该主机上特定的应用程序或服务。它可以看作是一个门,通过该门可以与特定的应用程序进行交流。

        端口号是一个16位的整数,范围从0到65535。其中,0到1023的端口号被称为“知名端口”(Well-known Ports),用于标识一些常见的服务,如HTTP(端口号80)、FTP(端口号21)等。1024到49151之间的端口号被称为“注册端口”(Registered Ports),用于一些已经注册的应用程序。49152到65535之间的端口号被称为“动态或私有端口”(Dynamic or Private Ports),通常由操作系统动态分配给客户端应用程序。

        通过使用源IP地址、目标IP地址和端口号,可以唯一确定网络中的通信路径。发送方将数据发送到目标主机的特定端口,接收方根据目标端口来接收和处理数据。

        端口的作用是实现多个应用程序同时在同一台设备上进行网络通信使得网络上的数据可以正确地路由到目标应用程序。通过将数据包与特定的端口相关联,网络设备可以将数据传递给正确的应用程序,并实现应用层之间的通信。

        总结而言,端口是在计算机网络中用于标识不同应用程序或服务的数字,它通过与IP地址一起使用,帮助网络设备正确地路由和交付数据。

注意:我们自己开发的程序选择注册端口,且一个设备中不能出现两个程序的端口号一样,否则出错。

(3)、协议:  

        协议(Protocol)是在计算机网络中定义数据通信规则和标准的集合。它规定了网络中各个设备之间如何进行通信、数据格式的结构、错误处理等细节,确保信息能够按照特定的方式传输和解释。

        在计算机网络中,不同的设备和应用程序需要遵循相同的协议来进行有效的通信。协议定义了数据交换的规则和语义,使得通信双方能够理解和解释彼此发送和接收的数据。

常见的网络协议有很多,其中一些重要的包括:

  1. TCP/IP协议:TCP/IP(Transmission Control Protocol/Internet Protocol)是互联网最基本的协议族,它定义了数据在网络中的传输方式和规则,包括IP地址分配、数据路由、数据分片、错误检测和纠错等。TCP/IP协议族包括了多个协议,如IP协议、TCP协议、UDP协议等。

  2. HTTP协议:HTTP(Hypertext Transfer Protocol)是一种应用层协议,用于在Web浏览器和Web服务器之间传输超文本数据。它定义了浏览器发送请求和服务器响应请求的格式和规则,是Web应用程序最常用的协议之一。

  3. FTP协议:FTP(File Transfer Protocol)是用于在网络上进行文件传输的协议。它定义了客户端和服务器之间进行文件传输的规则,包括建立连接、身份验证、文件上传和下载等。

  4. SMTP协议:SMTP(Simple Mail Transfer Protocol)是用于电子邮件传输的协议。它规定了电子邮件的传输方式、信封格式、消息格式等,确保电子邮件能够从发送方传递到接收方。

  5. DNS协议:DNS(Domain Name System)是将域名转换为IP地址的协议。它提供了一个分布式的命名系统,将人类可读的域名映射到计算机可识别的IP地址,实现了域名解析的功能。

        这些只是众多网络协议中的一小部分,每个协议都有不同的功能和应用领域。通过遵守共同的协议标准,网络设备和应用程序可以相互通信并完成特定的任务。协议的使用使得计算机网络能够高效、可靠地运行,并实现各种功能和服务。

UDP协议:

  • UDP是一种无连接不可靠传输的协议。
  • 将数据源IP、目的地IP和端口封装成数据包,不需要建立连接
  • 每个数据包的大小限制在64KB
  • 发送不管对方是否准备好,接收方收到也不确认,故是不可靠的
  • 可以广播发送 ,发送数据结束时无需释放资源,开销小,速度快。

UDP通信的特点: 

  1. 无连接性:UDP是无连接的传输协议,意味着在发送数据之前不需要建立连接。每个数据包都是独立的,由源主机直接发送到目标主机。
  2. 速度快:UDP没有像TCP那样的握手过程和其他的控制机制,因此传输速度较快。
  3. 简单:相对于TCP,UDP协议更加简单,头部开销较小。
  4. 不可靠:UDP不提供可靠性保证,因为它不处理丢失、重复或乱序的数据包。这意味着在数据传输过程中可能存在丢包的风险。
  5. 适合实时应用:由于UDP的快速传输和较低的延迟,它在对实时性要求较高的应用中表现良好,如语音通话、视频流等。

 二、常用类及其方法

 1. DatagramSocket类

    DatagramSocket表示一个UDP套接字,用于发送和接收数据报。它提供了与底层网络通信相关的方法。 

常用方法:

  • DatagramSocket():创建一个未绑定到任何本地地址和端口的新套接字。
  • DatagramSocket(int port):创建一个绑定到指定本地端口的新套接字。
  • void send(DatagramPacket packet):将指定的数据包发送到目标主机。
  • void receive(DatagramPacket packet):从套接字中接收数据包。

2. DatagramPacket 类

    DatagramPacket表示一个UDP数据包,包含要发送或接收的数据以及目标主机的地址和端口号。

常用方法: 

  • DatagramPacket(byte[] data, int length):使用指定的数据和长度创建一个无发送地址或端口号的数据包。
  • DatagramPacket(byte[] data, int offset, int length):使用指定的数据、偏移量和长度创建一个无发送地址或端口号的数据包。
  • DatagramPacket(byte[] data, int offset, int length, InetAddress address, int port):使用指定的数据、偏移量、长度、目标主机地址和端口号创建一个数据包。
  • byte[] getData():获取该数据包的数据。
  • InetAddress getAddress():获取该数据包的目标主机地址。
  • int getPort():获取该数据包的目标端口号。

3. InetAddress类

   InetAddress表示一个IP地址,并提供了与IP地址相关的方法。

常用方法:

  • public static InetAddress getLocalHost():返回本主机的地址对象。
  • public static InetAddress getByName​(String host):得到指定主机的IP地址对象,参数是域名或者IP地址。
  • public String getHostName​():获取此IP地址的主机名。
  • public String getHostAddress​():返回IP地址字符串。
  • public boolean isReachable(int timeout):在指定毫秒内连通该IP地址对应的主机,连通返回true。

 三、udp例子

 MainActivity:

package com.example.udpdemo;



import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
    Button sendBtn, decideBtn;
    EditText sendMsg, ipEd;
    TextView receiveMsg;
    // 对方的ip地址
    String ip;
    UdpTool udpTool;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();

        // 发送信息的函数
        sendBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //在Android通信协议必须要放在线程里面进行
                String str = sendMsg.getText().toString();
                Log.v("发送", str);
                if (ip!=null){
                    udpTool.sendMessage(str,ip);
                }else {
                    Toast.makeText(MainActivity.this, "请输入对方ip和端口", Toast.LENGTH_SHORT).show();
                }
            }

        });
        decideBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ip = ipEd.getText().toString();
                Toast.makeText(MainActivity.this, "确定成功!", Toast.LENGTH_SHORT).show();
            }
        });
        // 接收信息的函数
        try {
            udpTool.receiveMessage(receiveMsg);;
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void initView() {
        sendBtn = findViewById(R.id.send_btn);
        sendMsg = findViewById(R.id.send_message);
        receiveMsg = findViewById(R.id.receive_message);
        ipEd = findViewById(R.id.target_ip_ed);
        decideBtn = findViewById(R.id.decide_btn);
        udpTool = new UdpTool(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 释放资源
        udpTool.closeSocket();
    }
}

 UdpTool :

package com.example.udpdemo;

import android.content.Context;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UdpTool {
    private String TAG = "UdpTool";
    DatagramSocket mSocket;
    Context context;
    public UdpTool(Context context){
        this.context = context;
    }
    /**
     * 发送信息
     * @param msg 信息内容
     * @param ip 对方ip地址
     */
    public void sendMessage(String msg, String ip){
        // 需要开线程来发数据
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (mSocket == null){
                    try {
                        // 这个是本机的端口号
                        mSocket = new DatagramSocket(20010);

                    } catch (SocketException e) {
                        e.printStackTrace();
                    }
                }
                // 将字符串转换成字节流,因为底层的传输都是字节传输
                byte[] data = msg.getBytes();
                try {
                    // 对方ip和端口
                    DatagramPacket pack = new DatagramPacket(data, data.length, InetAddress.getByName(ip), 60011);
                    mSocket.send(pack);
                    Log.d(TAG, "发送成功!");
                } catch (IOException e) {
                    Log.d(TAG, "发送失败!");
                    e.printStackTrace();
                }
            }
        }).start();
    }
    /**
     * 接收消息的函数
     */
    public void receiveMessage(TextView tv) throws Exception {
        // 创建线程,同理,接收信息也要放在线程里面接收
        new Thread(new Runnable() {
            public void run() {
                try {
                    if (mSocket == null) {
                        mSocket = new DatagramSocket(60011);
                    }
                    String str;
                    while (true) {
                        // 创建一个空的字节数组
                        byte[] data = new byte[1024];
                        // 将字节数组和数组的长度传进DatagramPacket 创建的对象里面
                        DatagramPacket pack2 = new DatagramPacket(data, data.length);
                        Log.v("s", "pack2");
                        Log.v("s", "开始 接收");
                        try {
                            // socket对象接收pack包,程序启动的时候,socket会一直处于阻塞状态,直到有信息传输进来
                            mSocket.receive(pack2);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        // 获取发送数据的IP地址
                         String ip = pack2.getAddress().getHostAddress();
                        // 获取发送数据端的端口号
                         int port = pack2.getPort();
                        str = new String(pack2.getData(), 0, pack2.getLength()); // 将字节数组转化成字符串表现出来
                        // 开启接收端口后会持续接收数据,只有页面可见的时候才将收到的数据写入
                            tv.setText(str);
                        Toast.makeText(context, "IP地址:"+ip+"端口:"+port, Toast.LENGTH_SHORT).show();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 关闭通信
     */
    public void closeSocket() {
        if (mSocket != null) {
            mSocket.close();
            mSocket = null;
        }
    }
}

 activity_main:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:gravity="center"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <TextView

            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:text="对方IP地址:"/>
        <EditText
            android:id="@+id/target_ip_ed"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            android:textSize="20sp"/>
    </LinearLayout>

        <Button
            android:id="@+id/decide_btn"
            android:layout_width="80dp"
            android:layout_height="50dp"
            android:layout_gravity="center"
            android:gravity="center"
            android:textSize="20sp"
            android:text="确定"/>

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:orientation="vertical"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:text="发送信息端:"/>

        <EditText
            android:id="@+id/send_message"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:textSize="20sp"
            android:hint="发送的消息"
            android:background="@color/teal_200"
            android:gravity="center"/>
        <Button
            android:id="@+id/send_btn"
            android:layout_width="80dp"
            android:layout_height="50dp"
            android:layout_gravity="center"
            android:gravity="center"
            android:textSize="20sp"
            android:text="发送"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:orientation="vertical"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:text="接收信息端:"/>


        <TextView
            android:id="@+id/receive_message"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:hint="接收到的消息"
            android:textSize="20sp"
            android:background="@color/purple_500"
            android:gravity="center"/>
    </LinearLayout>




</LinearLayout>

权限:

<uses-permission android:name="android.permission.INTERNET"/>

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/841653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【图论】单源最短路

算法提高课笔记。&#xff08;本篇还未更新完… 目录 单源最短路的建图方式例题热浪题意思路代码 信使题意思路代码 香甜的黄油题意思路代码 最小花费题意思路代码 最优乘车题意思路代码 昂贵的聘礼题意思路代码 单源最短路的建图方式 最短路问题可以分为以下两类&#xff1a…

红队钓鱼技术之LNK快捷方式

简介 lnk文件是用于指向其他文件的一种文件。这些文件通常称为快捷方式文件&#xff0c;通常它以快捷方式放在硬盘上&#xff0c;以方便使用者快速的调用。lnk钓鱼主要将图标伪装成正常图标&#xff0c;但是目标会执行shell命令 步骤 1.编写shell命令 首先新建一个文本文件t…

解码大众全新数字高尔夫8汽车CAN FD行驶功能电气架构

据在大众原厂的伙伴介绍&#xff0c;全新数字高尔夫8将在11月上市销售&#xff0c;目前高尔夫8在行驶功能电气架构上采用的CAN FD&#xff0c;在多媒体这一块采用的以太网&#xff0c;后续估计大部分类似同样MQBEvo平台的车型均会复制升级过来&#xff0c;那么&#xff0c;未来…

An unexpected error has occurred. Conda has prepared the above report

今日在服务器上创建anaconda虚拟环境的时候&#xff0c;出现了如下报错 An unexpected error has occurred. Conda has prepared the above report 直接上解决方案 在终端中输入如下指令 conda config --show-sources 如果出现以下提示&#xff0c;说明多了一个文件 输入以下…

基于CentOS 7构建LVS-DR集群

DIPVIPRIPClient192.169.41.139 LVS 192.168.41.134192.169.41.10RS1192.168.41.135RS2192.168.41.138 要求&#xff1a; node4为客户端&#xff0c;node2为LVS&#xff0c;node3和node4为RS。 1.配置DNS解析&#xff08;我这里使用本地解析&#xff09; 192.168.41.134 www.y…

谷粒商城第十天-获取分类属性分组(前端组件抽取父子组件交互)

目录 一、总述 1.1 前端思路 1.2 后端思路 二、前端部分 2.1 将分类树前端代码抽取成一个组件 2.2 使用elementUI的组件实现左右组件功能 2.3 使用事件机制进行组件通信 三、后端部分 四、总结 一、总述 说一下今天需要实现一个什么样子的功能&#xff1a; 很简单&am…

Vue2:组件高级(上)

Vue2&#xff1a;组件高级&#xff08;上&#xff09; Date: May 20, 2023 Sum: 组件样式冲突、data函数、组件通信、props、组件生命周期、vue3.x中全局配置axios 目标&#xff1a; 能够掌握 watch 侦听器的基本使用 能够知道 vue 中常用的生命周期函数 能够知道如何实现组…

基于自组织竞争网络的患者癌症发病预测(matlab代码)

1.案例背景 1.1自组织竞争网络概述 前面案例中讲述的都是在训练过程中采用有导师监督学习方式的神经网络模型。这种学习方式在训练过程中,需要预先给网络提供期望输出,根据期望输出来调整网络的权重,使得实际输出和期望输出尽可能地接近。但是在很多情况下,在人们认知的过程中…

分布式规则引擎框架的设计

MirAIe 规则引擎是一个可扩展且可扩展的规则引擎框架&#xff0c;允许用户对多个活动进行分组和自动化。 过去几年&#xff0c;在开发MirAIe 物联网平台时&#xff0c;我们意识到需要一个可扩展、可扩展的规则引擎框架。规则引擎使您能够对各种操作进行分组、管理和自动化&…

git【潦草学习】

初始配置git 查询版本号 初次使用git前配置用户名与邮箱地址 git config --global user.name "your name" git config --global user.email "your email" git config -l 发现最后两行多出了用户名和邮箱&#xff0c;说明配置成功

对指针变量引用以及自定义类型引用的认识

#include <iostream> using namespace std; #include <iomanip>typedef int G[10]; //自定义类型void test(int* p); // void test_0(int &p); //表明p是一个int型变量的别名 void test_1(G &pG); //表明pG是一个G类型变量的别名 void test_2(int*…

PMP备考心得分享

备考PMP考试是一段充满挑战和成长的旅程。参加某机构的PMP培训课程&#xff0c;有国内PMP考培资深讲师的授课&#xff0c;以及班主任的周期监督管理&#xff0c;无疑是我备考成功的重要支撑。在这个过程中&#xff0c;我积累了许多宝贵的经验和心得&#xff0c;现在将它们分享给…

GPT-5出世,需5万张H100!英伟达GPU陷短缺风暴

随着人工智能技术的不断突破&#xff0c;自然语言处理领域也掀起了一波又一波的革命。从GPT-3.5的惊艳登场&#xff0c;到紧随其后的GPT-4的惊世震人&#xff0c;人们仿佛置身于科幻电影中&#xff0c;亲历了一场场技术的奇迹。然而&#xff0c;这场奇迹背后却逐渐显现出一道不…

解决问题:ModuleNotFoundError: No module named ‘mmcv._ext‘,及安装mmcv-full的详细教程

解决问题**ModuleNotFoundError: No module named ‘mmcv._ext’**之前得先搞懂mmcv和mmcv-full的关系。 mmcv 和 mmcv-full 都是针对 PyTorch 的计算机视觉基础库,两者的主要区别是: mmcv 包含了 mmcv 的核心组件,例如运行器、回调函数、可视化工具等,打包体积较小。mmcv-fu…

K8S系列文章之 自动化运维利器 Fabric

Fabric 主要用在应用部署与系统管理等任务的自动化&#xff0c;简单轻量级&#xff0c;提供有丰富的 SSH 扩展接口。在 Fabric 1.x 版本中&#xff0c;它混杂了本地及远程两类功能&#xff1b;但自 Fabric 2.x 版本起&#xff0c;它分离出了独立的 Invoke 库&#xff0c;来处理…

bigemap国土管理行业应用

由于国营企业单位&#xff0c;管理土地&#xff0c;必须要有这样的软件套图 客户之前用的谷歌&#xff0c;后来不能访问了&#xff0c;通过其他途径搜索到我们 客户使用软件一般都用于套坐标以及空间规划图&#xff0c;方便于项目选址和居民建房报建在卫星图上找到用地范围&am…

远程调试MySQL内核

1 vscode 需要安装remote-ssh插件 安装成功后&#xff0c;登录&#xff1a; 默认远程服务器的登录 ssh rootip注意&#xff0c;Linux需要设置root远程登录&#xff1b; 2 安装debug扩展 C\C extemsion Pack C\Cgdb debugger beyond用于进程attach 3 设置Attach进程 {// …

MyBatis源码剖析之Mapper代理方式细节

MyBatis是一个流行的Java持久层框架&#xff0c;它提供了多种方式来执行数据库操作&#xff0c;其中之一就是通过Mapper代理方式。通过Mapper代理方式&#xff0c;开发者可以编写接口&#xff0c;然后MyBatis会动态地生成接口的实现类&#xff0c;从而避免了繁琐的SQL映射配置。…

前端主题切换方案——CSS变量

前言 主题切换是前端开发中老生常谈的问题&#xff0c;本文将介绍主流的前端主题切换实现方案——CSS变量 CSS变量 简介 编写CSS样式时&#xff0c;为了避免代码冗余&#xff0c;降低维护成本&#xff0c;一些CSS预编译工具&#xff08;Sass/Less/Stylus&#xff09;等都支…

Java基础入门篇——Java注释、关键字和标识符(二)

目录 一、注释 1.1注释介绍 1.2单行注释 1.3多行注释 1.4文档注释 1.5javadoc注释标签语法 二、关键字 三、字面量 3.1什么是标识符&#xff1f; 3.2标识符命名规则 四、总结 一、注释 在Java中&#xff0c;注释是用来向代码添加解释、说明和文档信息的文本。Java…