安卓监听端口接收消息

其他文章

下面是我的另一篇文章,是在电脑上发送数据,配合本篇文章,可以实现电脑与手机的局域网通讯。直接复制粘贴就能行,非常滴好用。
点击连接
另外,如果你不知道你的手机ip,也可以通过如下文章获取哦,这文章的是局域网IP,限于局域网测试。
点击连接

监听端口

我们可以创建一个DatagramSocket对象,用于在指定的端口上接收UDP消息。

DatagramSocket是Java中用于进行UDP通信的类,它代表一个数据报套接字。通过DatagramSocket对象,我们可以发送和接收UDP数据报。

示例代码如下:

val udpSocket = DatagramSocket(port)

port变量是指定的端口号,用于指定UDP套接字绑定的端口。创建的udpSocket对象将在目标端口号上进行监听,用于接收来自其他节点的UDP消息。

接收消息

一旦创建了DatagramSocket对象,就可以使用该对象的receive方法来接收UDP消息,并将接收到的数据存储在一个DatagramPacket对象中,然后通过解析DatagramPacket对象来获取实际的消息内容。
示例代码如下:

val buffer = ByteArray(1024)
val packet = DatagramPacket(buffer, buffer.size)
udpSocket.receive(packet)

接收到消息后,就可以进行相应的处理操作,比如更新UI等。

建立新线程

在Android开发中,主线程(也称为UI线程)负责处理用户界面的更新和响应用户交互事件,包括处理用户输入、渲染界面等操作。如果在主线程中执行耗时的操作,如网络请求、文件读写等,会导致界面卡顿、无响应或ANR错误。

为避免这种情况,在执行网络数据的接收操作时,需要使用Thread来创建一个新的线程。将耗时的操作放在新的线程中执行,保持主线程的响应性。这样,主线程仍然可以继续处理用户界面的更新和事件,而不会因为阻塞在接收消息操作上而产生卡顿或无响应的情况。

开启新线程,首先创建一个Thread对象,并传入一个Runnable对象作为参数。Runnable对象定义了线程要执行的操作。
示例代码如下:

val receiveThread = Thread(Runnable {
})

在线程中,我们可以通过Thread.currentThread()方法获得当前执行的线程对象。
而通过线程对象的isInterrupted()方法可以检查当前线程是否被中断。如果线程被中断,isInterrupted()方法会返回true,否则返回false。
如此一来,我们可以在线程中通过一个循环,来不断的接收数据。
示例代码如下:

while (!Thread.currentThread().isInterrupted) {
}

循环条件表示当当前线程不被中断时执行循环体内的代码。这样程序就在后台线程中执行持续性的任务,直到线程被中断或任务完成才退出循环。

当然了,要在循环体内部结束循环的话,只要执行Thread.currentThread().interrupt()方法即可,该方法会中断当前线程。然后isInterrupted()方法将会返回true,循环条件将不再满足,从而退出循环。这可以用来停止线程的执行并终止循环。

最后我们得到如下代码:

val receiveThread = Thread(Runnable {
    val udpSocket = DatagramSocket(port)
    val buffer = ByteArray(1024)
    val packet = DatagramPacket(buffer, buffer.size)

    while (!Thread.currentThread().isInterrupted) {
        try {
            udpSocket.receive(packet)
            val receivedData: String = String(packet.data, 0, packet.length)
            runOnUiThread {
                updateReceivedMessage(receivedData)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    udpSocket.disconnect()
    udpSocket.close()
})

在Runnable对象的run方法中,我们创建了一个DatagramSocket对象,并指定了要监听的端口号。然后我们创建了一个字节数组buffer以及一个DatagramPacket对象packet,用于接收UDP数据。
在循环中,我们使用udpSocket.receive(packet)方法来接收数据。一旦有数据到达,receive方法会阻塞,直到数据到达或者发生异常。当数据到达后,使用packet对象从接收到的数据中提取字符串,并调用runOnUiThread方法来在UI线程中更新界面上的receivedMessageTextView的文本内容,显示接收到的消息。

在循环结束后,记得关闭udpSocket连接。

完整代码

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.widget.TextView
import java.net.DatagramPacket
import java.net.DatagramSocket

class MainActivity : AppCompatActivity() {
    private val port = 8888

    private lateinit var receivedMessageTextView: TextView

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

        receivedMessageTextView = findViewById(R.id.tv_received_message)

        val receiveThread = Thread(Runnable {
            val udpSocket = DatagramSocket(port)
            val buffer = ByteArray(1024)
            val packet = DatagramPacket(buffer, buffer.size)

            while (!Thread.currentThread().isInterrupted) {
                try {
                    udpSocket.receive(packet)
                    val receivedData: String = String(packet.data, 0, packet.length)
                    runOnUiThread {
                        updateReceivedMessage(receivedData)
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
            udpSocket.disconnect()
            udpSocket.close()
        })

        receiveThread.start()
    }

    private fun updateReceivedMessage(message: String) {
        receivedMessageTextView.text = message
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是一套基本的 Android Studio 应用程序,可以监听所选 WiFi 和所填端口下的消息: 1. 在 AndroidManifest.xml 文件中添加以下权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> ``` 2. 在 layout 文件夹中创建一个新的布局文件,例如 activity_main.xml。该布局文件应包含以下部分: a. 一个 EditText 用于输入要监听端口号; b. 一个 ListView 用于显示接收到的消息; c. 一个 Button 用于开始和停止监听; d. 一个 Spinner 用于选择要监听的 WiFi 网络。 以下是示例代码: ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <EditText android:id="@+id/portEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter port number" /> <ListView android:id="@+id/messageListView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <Button android:id="@+id/listenButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Listen" /> <Spinner android:id="@+id/wifiSpinner" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> ``` 3. 在 MainActivity.java 文件中,定义以下变量: ```java private EditText portEditText; private ListView messageListView; private Button listenButton; private Spinner wifiSpinner; private boolean isListening = false; private ServerSocket serverSocket; private Socket clientSocket; private InputStream inputStream; private OutputStream outputStream; private ArrayAdapter<String> messageAdapter; ``` 4. 在 onCreate() 方法中,初始化这些变量,并为 Spinner 添加所需的 WiFi 网络列表: ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化变量 portEditText = findViewById(R.id.portEditText); messageListView = findViewById(R.id.messageListView); listenButton = findViewById(R.id.listenButton); wifiSpinner = findViewById(R.id.wifiSpinner); messageAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); messageListView.setAdapter(messageAdapter); // 为 Spinner 添加 WiFi 列表 WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); List<ScanResult> scanResults = wifiManager.getScanResults(); List<String> wifiList = new ArrayList<>(); for (ScanResult scanResult : scanResults) { wifiList.add(scanResult.SSID); } ArrayAdapter<String> wifiAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, wifiList); wifiAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); wifiSpinner.setAdapter(wifiAdapter); } ``` 5. 实现 startListening() 和 stopListening() 方法: ```java private void startListening() { isListening = true; listenButton.setText("Stop"); new Thread(new Runnable() { @Override public void run() { try { int port = Integer.parseInt(portEditText.getText().toString()); serverSocket = new ServerSocket(port); clientSocket = serverSocket.accept(); inputStream = clientSocket.getInputStream(); outputStream = clientSocket.getOutputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null && isListening) { runOnUiThread(new Runnable() { @Override public void run() { messageAdapter.add(line); } }); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } private void stopListening() { isListening = false; listenButton.setText("Listen"); try { serverSocket.close(); clientSocket.close(); inputStream.close(); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } ``` 6. 在 onCreate() 方法中,为 listenButton 添加点击事件,实现开始和停止监听的功能: ```java listenButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isListening) { stopListening(); } else { startListening(); } } }); ``` 7. 最后,在 AndroidManifest.xml 文件中添加以下代码,声明 MainActivity 作为应用程序的入口点: ```xml <application ... <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> ``` 这样,您的 Android 应用程序就可以在所选 WiFi 和所填端口监听消息了。请注意,此示例代码只是一个基本的框架,您需要根据实际情况进行调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水智

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值