一、布局文件
<?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">
<TextView
android:id="@+id/receiveText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="接收到的消息"
android:gravity="center"/>
<EditText
android:id="@+id/sendText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="发送的消息"
android:gravity="center"
android:layout_marginTop="50dp"
android:layout_marginBottom="50dp"/>
<Button
android:id="@+id/sendBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送"/>
</LinearLayout>
二、使用
package com.example.udp;
import androidx.appcompat.app.AppCompatActivity;
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 java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private boolean isText = false;
DatagramSocket socket;
Button btn;
EditText et;
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) this.findViewById(R.id.sendBtn);
et = (EditText) this.findViewById(R.id.sendText);
tv = (TextView) this.findViewById(R.id.receiveText);
// 发送信息的函数
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
//在Android通信协议必须要放在线程里面进行
String str = et.getText().toString();
Log.v("发送", str);
sendMsg(str);
}
}).start();
}
});
// 接收信息的函数
try {
receiveMsg();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 发送消息的函数
*/
public void sendMsg(String msg) {
Log.v("v", "开始发送");
try {
if (socket == null) {
// 20020是本机的端口号
socket = new DatagramSocket(20020);
}
//将字符串转换成字节流,因为底层的传输都是字节传输
byte data[] = msg.getBytes();
// 对方的IP和端口号
DatagramPacket pack = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.124.17"), 60000); // 创建DatagramPacket 对象数据包,这里的60000是我们要发送信息主机的端口号
socket.send(pack);
Log.v("f", "发送成功!");
} catch (Exception e) {
Log.v("f", "发送失败!");
e.printStackTrace();
}
}
/**
* 接收消息的函数
*/
public void receiveMsg() throws Exception {
// 创建线程,同理,接收信息也要放在线程里面接收
new Thread(new Runnable() {
public void run() {
try {
if (socket == null) {
socket = new DatagramSocket(60000);
}
String str;
List<Byte> bytes = new ArrayList<>();
List list = new ArrayList();
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会一直处于阻塞状态,直到有信息传输进来
socket.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()); // 将字节数组转化成字符串表现出来
// 开启接收端口后会持续接收数据,只有页面可见的时候才将收到的数据写入
if (isText) {
tv.setText(str);
}
}
} catch (SocketException e) {
e.printStackTrace();
}
}
}).start();
}
@Override
protected void onStart() {
super.onStart();
isText = true;
}
@Override
protected void onStop() {
super.onStop();
isText = false;
}
@Override
protected void onDestroy() {
super.onDestroy();
// 释放资源
if (socket != null) {
socket.close();
}
}
}