Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >数据报(UDP)接收器不工作-未接收广播数据包

数据报(UDP)接收器不工作-未接收广播数据包
EN

Stack Overflow用户
提问于 2021-05-12 12:35:53
回答 1查看 341关注 0票数 0

我遇到了UDP数据报的问题,因为我不能从服务器接收UDP数据包,但我可以发送它们。我看了很多例子,但都不知道我的代码出了什么问题。我终于从不同的网站找到了哪里出了问题的线索。

因此,我在这里更新了这个问题,以防它在未来可能会对某人有所帮助。下面的代码是在LG手机上的WiFi网络上运行的,构建在Android Studio4.2(2021年2月4日);SDK Platform 30;Kotlin 1.5.0上

在下面的代码部分的末尾,我写了一些关于是什么导致我的代码不能工作的注释。

这是我的MainActivity代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//Required includes
import android.os.Bundle
import android.os.StrictMode
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.io.IOException
import java.net.*


class MainActivity : AppCompatActivity() {

    //declared variables
    private var clientThread: ClientThread? = null
    private var thread: Thread? = null
    private var tv:TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_new)

        //Create a thread so that the received data does not run within the main user interface
        clientThread = ClientThread()
        thread = Thread(clientThread)
        thread!!.start()

        // create a value that is linked to a button called (id) MyButton in the layout
        val buttonPress = findViewById<Button>(R.id.MyButton)
        tv = findViewById(R.id.rcvdData)
        tv!!.text = "Data Captured"

        //Create a listener that will respond if MyButton is clicked
        buttonPress.setOnClickListener{
            //send a UDP package as a test
            sendUDP("Hello")
        }
    }



    //************************************ Some test code to send a UDP package
    fun sendUDP(messageStr: String) {
        // Hack Prevent crash (sending should be done using a separate thread)
        val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
        StrictMode.setThreadPolicy(policy)  //Just for testing relax the rules...
        try {
            //Open a port to send a UDP package
            val socket = DatagramSocket()
            socket.broadcast = true
            val sendData = messageStr.toByteArray()
            val sendPacket = DatagramPacket(sendData, sendData.size, InetAddress.getByName(SERVER_IP), SERVERPORT)
            socket.send(sendPacket)
            println("Packet Sent")
        } catch (e: IOException) {
            println(">>>>>>>>>>>>> IOException  "+e.message)
        }
    }

    //************************************* Some test code for receiving a UDP package
    internal inner class ClientThread : Runnable {
        private var socket: DatagramSocket? = null
        private val recvBuf = ByteArray(1500)
        private val packet = DatagramPacket(recvBuf, recvBuf.size)
        // **********************************************************************************************
        // * Open the network socket connection and start receiving a Byte Array                        *
        // **********************************************************************************************
        override fun run() {

            try {
                //Keep a socket open to listen to all the UDP trafic that is destined for this port
                socket = DatagramSocket(CLIENTPORT)
                while (true) {
                    //Receive a packet
                    socket!!.receive(packet)  

                    //Packet received
                    println("Packet received from: " + packet.address.hostAddress)
                    val data = String(packet.data).trim { it <= ' ' }
                    println("Packet received; data: $data")
                    //Change the text on the main activity view
                    runOnUiThread { tv?.text = data }
                }
            }
            catch (e1: IOException) {
                println(">>>>>>>>>>>>> IOException  "+e1.message)
                socket?.close()
            }
            catch (e2: UnknownHostException) {
                println(">>>>>>>>>>>>> UnknownHostException  "+e2.message)
                socket?.close()
            }
            finally{
                socket?.close()
            }
        }
    }

    companion object {
        val CLIENTPORT = 3000
        val SERVERPORT = 3000
        val SERVER_IP = "192.168.8.102"
    }
}

我在清单文件中添加了以下权限

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<uses-permission android:name="android.permission.INTERNET"/>

"activity_new.xml“只包含一个id为MyButton的按钮和一个id为rcvdData的TextView

gradle.build (项目)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
buildscript {
    ext.kotlin_version = "1.5.0"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.2.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

gradle.build (模块)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.example.udptry1"
        minSdkVersion 23
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

虽然我可以发送数据报UDP数据包,但我不能接收它们。在最终正确接收UDP数据包后,我只能接收单播消息(仅针对我的IP的消息),而不能接收广播消息(针对多个设备的消息)。

我不能接收消息的原因是我在我的PC上模拟接收器。Android的模拟器会改变被模拟设备的IP地址,而不会将其绑定到PC的IP地址。这意味着,虽然我的PC可以接收广播的消息,但模拟的电话不会。有关更多详细信息,请查看此链接(https://developer.android.com/studio/run/emulator-networking)

我只能接收单播而不能广播消息的原因是,一旦我的手机上的代码正常工作,我就会在编码时离开手机。这意味着手机屏幕将进入休眠状态。显然,有大量的手机在手机进入睡眠状态时为了省电而禁止收听广播信息。一旦手机被唤醒,它就会收听广播消息。

在我的手机上获取多点传送锁似乎不会影响这个功能(我只尝试了广播,所以不幸的是,我不知道如果你真的在使用多点传送套接字而不是datagramsocket的话,它是否可以工作)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-15 08:17:10

我已经找到了解决方案。代码实际上没有任何问题。我已经更新了原始问题,并对导致问题的原因发表了评论……请参阅上面的问题以获得完整的解释。

简而言之,问题在于Android的模拟器与PC的IP地址不同,其次,一旦进入休眠状态,手机就会停止收听广播的消息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67503820

复制
相关文章
Linux下多线程程序为什么消耗大量虚拟内存
最近游戏已上线运营,进行服务器内存优化,发现一个非常奇妙的问题,我们的认证服务器(AuthServer)负责跟第三方渠道SDK打交道(登陆和充值),由于采用了curl阻塞的方式,所以这里开了128个线程,奇怪的是每次刚启动的时候占用的虚拟内存在2.3G,然后每次处理消息就增加64M,增加到4.4G就不再增加了,由于我们采用预分配的方式,在线程内部根本没有大块分内存,那么这些内存到底是从哪来的呢?让人百思不得其解。 探索 一开始首先排除掉内存泄露,不可能每次都泄露64M内存这么巧合,为了证明我的观点,首先,我使用了valgrind。
Debian中国
2018/12/20
2.1K0
减少Redis内存消耗的优化措施
当命令请求被执行时,Redis会将数据从磁盘加载到内存中进行处理,这会导致内存的消耗。
一凡sir
2023/09/27
4900
减少Redis内存消耗的优化措施
使用top命令查看最消耗CPU和最消耗内存的进程
在终端执行top命令后,  在top基本视图中,按键盘数字“1”,可监控每个逻辑CPU的状况: 快捷键shift + p  : 将进程按照CPU占用从大到小排序。  快捷键shift + m  : 将进程按照内存占用从大到小排序。
joshua317
2018/04/16
1.9K0
如何降低 Python 的内存消耗量?
在执行程序时,如果内存中有大量活动的对象,就可能出现内存问题,尤其是在可用内存总量有限的情况下。在本文中,我们将讨论缩小对象的方法,大幅减少Python所需的内存。
Python猫
2019/08/08
1.6K0
如何降低 Python 的内存消耗量?
Oracle进程内存结构-如何察看Oracle进程消耗的内存
经常有人问到如何在Unix下确定进程消耗的内存资源,以及为何Top工具的显示非常高。 有人说Top的输出不精确,这种说法是不确切的。实际上是Top输出显示的Oracle进程内存使用,包含了SGA部分。这也是SGA的意义所在。 SGA可以被共享,可以被所有进程所访问,在进程的寻址空间里就包含了SGA的大小。
数据和云01
2018/09/10
3.4K0
Linux进程内存消耗指标解读
物理内存:不解释 虚拟内存:进程独享,由操作系统通过地址映射的方式,转换为对物理内存的访问。在32位Linux机器上,每个进程的虚拟内存都是4G。(这里的虚拟内存与操作系统使用中过程常见的虚拟内存概念不同,不要混淆了,如Linux中swap)
十毛
2019/03/27
6.1K0
pmap查看某进程所消耗的内存
[[Address: 内存开始地址]\ [Kbytes: 占用内存的字节数(KB)]\ [RSS: 保留内存的字节数(KB)]\ [Dirty: 脏页的字节数(包括共享和私有的)(KB)]\ [Mode: 内存的权限:read、write、execute、shared、private (写时复制)]\ [Mapping: 占用内存的文件、或[anon](分配的内存)、或[stack](堆栈)]\ [Offset: 文件偏移]\ [Device: 设备名 (major:minor)]
明哥的运维笔记
2019/01/30
3.2K0
一文了解 Redis 内存监控和内存消耗
Redis 是一种内存数据库,将数据保存在内存中,读写效率要比传统的将数据保存在磁盘上的数据库要快很多。所以,监控 Redis 的内存消耗并了解 Redis 内存模型对高效并长期稳定使用 Redis 至关重要。
程序员历小冰
2019/12/06
1.1K0
一文了解 Redis 内存监控和内存消耗
一文了解 Redis 内存监控和内存消耗
Redis 是一种内存数据库,将数据保存在内存中,读写效率要比传统的将数据保存在磁盘上的数据库要快很多。所以,监控 Redis 的内存消耗并了解 Redis 内存模型对高效并长期稳定使用 Redis 至关重要。
程序员历小冰
2019/10/15
9270
一文了解 Redis 内存监控和内存消耗
MySQL内存到底消耗在哪里?
一说起MySQL使用的内存,你可能会想到各种buffer,最著名的莫过于innodb buffer pool了,它是内存使用的大户,还有sort buffer等等。除了这些buffer之外,可能还有一些细枝末节,今天我们来总结一下。
AsiaYe
2021/12/04
3K0
Percona Server 5.1 内存过量消耗分析
一次巡检过程中发现数据库使用内存有些过量,innodb_buffer_pool_size 设置值为 20G ,但实际物理内存消耗为 37G ,总虚拟内存消耗达 42G ,直接导致监控报警,于是开启了一次内存使用探究之旅,整理出来和大家分享一下
franket
2022/07/09
5320
一文了解 Redis 内存监控和内存消耗
Redis 是一种内存数据库,将数据保存在内存中,读写效率要比传统的将数据保存在磁盘上的数据库要快很多。所以,监控 Redis 的内存消耗并了解 Redis 内存模型对高效并长期稳定使用 Redis 至关重要。
Bug开发工程师
2019/11/12
1.3K0
如何测量Ceph OSD内存占用
这个工具我第一次看到是在填坑群里面看到,是由研发-北京-蓝星同学分享的,看到比较有趣,就写一篇相关的记录下用法
用户2772802
2018/08/06
1.8K0
如何测量Ceph OSD内存占用
Percona Server 5.1 内存过量消耗分析6
由于它并不能动态进行调整,所以必须安排一次数据库的启停,在配置文件中对 innodb_ibuf_max_size 进行限定就可以有效解决此问题
franket
2022/07/09
6050
MySQL一次大量内存消耗的跟踪
线上使用MySQL8.0.25的数据库,通过监控发现数据库在查询一个视图(80张表的union all)时内存和cpu均明显上升。
GreatSQL社区
2023/08/11
2580
MySQL一次大量内存消耗的跟踪
Percona Server 5.1 内存过量消耗分析1
分析问题初步推断有两种情况:参数配置不当内存泄漏关于参数配置不当,我分析完各种buffer,cache参数配置后没有发现异常或特别严重的错误,于是尝试从内存泄漏的角度来寻找突破口----分析工具pmap : 用来生成一个进程的内存使用报表The pmap command reports the memory map of a process or processes.pt-config-diff : 用来比较Mysql 配置文件的差异pt-config-diff diffs MySQL configurat
franket
2022/07/09
6140
实用脚本:检查高 CPU / 内存消耗进程
该脚本将显示进程 ID、进程的所有者、进程的名称以及进程的运行时间。这将帮助你确定哪些(必须事先完成)作业正在超时运行。这可以使用 ps 命令来实现。
用户8639654
2021/09/16
1.4K0
Percona Server 5.1 内存过量消耗分析4
由于 innodb_buffer_pool_size 和 query_cache_size 都是我手动配置的,所以这个差异报告让我立刻注意到了 innodb_ibuf_max_size
franket
2022/07/09
4910
对线面试官-Redis(内存消耗的问题)
面试官:Hi,上次我们聊到了Redis作为缓存的数据一致性问题,这次我们继续聊一聊Redis作为缓存的问题之内存消耗问题?
@派大星
2023/06/28
1840
对线面试官-Redis(内存消耗的问题)
Percona Server 5.1 内存过量消耗分析2
对这个报表作一个排序,会获得更多信息[root@abc ~]# pmap -x 14769 | sort -nk 2 ---------------- ------ ------ ------14769: /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --log-error=/var/lib/mysql/abc.err --open-files-limit=8192 --pid-file=/var/lib
franket
2022/07/09
4980

相似问题

测量CPU/内存消耗

13

测量make run的内存消耗

10

线程内存消耗

14

测量顶级内存消耗(linux程序)

21

如何测量webview消耗的内存量?

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文