android udp 设备发现,Android局域网内快速查找某个设备的IP地址(UDP通信)

需求:通过udp传输方式,快速找到同局域网内某设备

思路:需要某设备发送,手机接收。或者手机发送,设备接收,两个设备需在同一局域网内

1、建立udpsocket服务

2、提供数据,并将数据封装到数据包中

3、通过socket服务的发送功能,将数据包发送出去。

4、关闭资源。

DatagramSocket:此类表示用来发送和接收数据报包的套接字。在 DatagramSocket 上总是启用 UDP 广播发送。

DatagramPacket:此类表示数据报包。数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。

先看个图:

UDP发送数据

35ebd7f2eac06b13f4b52935ef63d4c8.png

UDP接收数据

fb6bac2ef62309d14fedba3be7c9ff38.png

具体代码如下:

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);

}

}

}

最后别忘了网络权限: