需求:通過udp傳輸方式,快速找到同局域網內某設備
思路:需要某設備發送,手機接收。或者手機發送,設備接收,兩個設備需在同一局域網內
1、建立udpsocket服務
2、提供數據,並將數據封裝到數據包中
3、通過socket服務的發送功能,將數據包發送出去。
4、關閉資源。
DatagramSocket:此類表示用來發送和接收數據報包的套接字。在 DatagramSocket 上總是啓用 UDP 廣播發送。
DatagramPacket:此類表示數據報包。數據報包用來實現無連接包投遞服務。每條報文僅根據該包中包含的信息從一臺機器路由到另一臺機器。從一臺機器發送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。不對包投遞做出保證。
先看個圖:
UDP發送數據
UDP接收數據
具體代碼如下:
<?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"
android:orientation="vertical"
tools:context=".ui.activity.TestActivity">
<Button
android:id="@+id/btn_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="發送" />
<Button
android:id="@+id/btn_wait"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="開始等待接收" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-------------" />
</ScrollView>
</LinearLayout>
package com.fzm.coldwallet.ui.activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.fzm.coldwallet.R;
import com.fzm.coldwallet.ui.base.BaseActivity;
import com.fzm.coldwallet.utils.ToastUtils;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class TestActivity extends BaseActivity {
@BindView(R.id.btn_send)
Button btnSend;
@BindView(R.id.btn_wait)
Button btnWait;
@BindView(R.id.tv_data)
TextView tvData;
private MainHandle mMainHandle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ButterKnife.bind(this);
mMainHandle = new MainHandle();
}
@OnClick({R.id.btn_send, R.id.btn_wait})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.btn_send:
sendMsg();
break;
case R.id.btn_wait:
new Thread(new Runnable() {
@Override
public void run() {
waitMsg();
}
}).start();
break;
}
}
private String sLog = "";
private void sendMsg() {
try {
final DatagramSocket hostSocket = new DatagramSocket();
// 設置接收超時時間
hostSocket.setSoTimeout(1500);
final String sendData = "my name is zzz";
InetAddress broadIP = InetAddress.getByName("255.255.255.255");
final DatagramPacket sendPack = new DatagramPacket(sendData.getBytes(), sendData.length(), broadIP, 9901);
new Timer().schedule(new TimerTask() {
@Override
public void run() {
String log = sendData + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\n";
Log.v("tag", Thread.currentThread() + log);
if (sLog.split("\n").length > 10) {
sLog = "";
}
try {
hostSocket.send(sendPack);
sLog += log;
runOnUiThread(new Runnable() {
@Override
public void run() {
tvData.setText(sLog);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}, 0, 1000);
} catch (Exception e) {
e.printStackTrace();
}
}
private String rLog = "";
private void waitMsg() {
byte[] buffer = new byte[1024];
/*在這裏同樣使用約定好的端口*/
int port = 9901;
DatagramSocket server = null;
try {
server = new DatagramSocket(port);
final DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
// 等待主機的搜索
try {
server.receive(packet);
final String s = new String(packet.getData(), 0, packet.getLength(), "UTF-8");
String log = packet.getAddress() + ",port:" + packet.getPort() + "," + s + "\n";
Log.v("tag", log);
rLog += log;
if (rLog.split("\n").length > 10) {
rLog = "";
}
mMainHandle.sendEmptyMessage(1);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (SocketException e) {
e.printStackTrace();
} finally {
if (server != null)
server.close();
}
}
class MainHandle extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
tvData.setText(rLog);
}
}
}
最後別忘了網絡權限:
<uses-permission android:name="android.permission.INTERNET" />