导航:首页 > 操作系统 > android发送udp广播

android发送udp广播

发布时间:2023-01-06 13:44:48

1. android udp接收不到数据

1、可先在oncreate()方法里面实例化一个WifiManager.MulticastLock 对象lock;具体如下:
WifiManager manager = (WifiManager) this
.getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock lock= manager.createMulticastLock("test wifi");

2、在调用广播发送、接收报文之前先调用lock.acquire()方法;
3、用完之后及时调用lock.release()释放资源,否决多次调用lock.acquire()方法,程序可能会崩,详情请见
Caused by: java.lang.UnsupportedOperationException: Exceeded maximum number of wifi locks
注;记得在配置文件里面添加如下权限:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

经过这样处理后,多数手机都能正常发送接收到广播报文。
本小点转载自Android手机接收不到UDP报文
二、在UDP通信中,android端发送UDP广播包没有问题。至于接收的话,有时候不能接收到包。
在UDP通信中,android端发送UDP广播包没有问题。至于接收的话,有时候不能接收到包。但是如果UDP包中指定了目标主机的地址的话,那么android端就能正常接收。
下面上一段代码,大家可用这段代码进行测试。
1、在一个Service里面,我们创建一个线程

public void onCreate() {//用于创建线程
WifiManager manager = (WifiManager) this
.getSystemService(Context.WIFI_SERVICE);
udphelper = new UdpHelper(manager);

//传递WifiManager对象,以便在UDPHelper类里面使用MulticastLock
udphelper.addObserver(MsgReceiveService.this);
tReceived = new Thread(udphelper);
tReceived.start();
super.onCreate();
}

2、弄一个UDP帮助类,这个类主要用于发送和接收数据

package com.example.com.ihome.bang.util;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Observable;
import com.example.com.ihome.bang.tool.SendThread;
import android.net.wifi.WifiManager;
import android.util.Log;

/**
*
* UdpHelper帮助类
*
* @author 陈喆榕
*
*/
public class UdpHelper implements Runnable {
public Boolean IsThreadDisable = false;//指示监听线程是否终止
private static WifiManager.MulticastLock lock;
InetAddress mInetAddress;
public UdpHelper(WifiManager manager) {
this.lock= manager.createMulticastLock("UDPwifi");
}
public void StartListen() {
// UDP服务器监听的端口
Integer port = 8903;
// 接收的字节大小,客户端发送的数据不能超过这个大小
byte[] message = new byte[100];
try {
// 建立Socket连接
DatagramSocket datagramSocket = new DatagramSocket(port);
datagramSocket.setBroadcast(true);
DatagramPacket datagramPacket = new DatagramPacket(message,
message.length);
try {
while (!IsThreadDisable) {
// 准备接收数据
Log.d("UDP Demo", "准备接受");
this.lock.acquire();

datagramSocket.receive(datagramPacket);
String strMsg=new String(datagramPacket.getData()).trim();
Log.d("UDP Demo", datagramPacket.getAddress()
.getHostAddress().toString()
+ ":" +strMsg );this.lock.release();
}
} catch (IOException e) {//IOException
e.printStackTrace();
}
} catch (SocketException e) {
e.printStackTrace();
}

}
public static void send(String message) {
message = (message == null ? "Hello IdeasAndroid!" : message);
int server_port = 8904;
Log.d("UDP Demo", "UDP发送数据:"+message);
DatagramSocket s = null;
try {
s = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
}
InetAddress local = null;
try {
local = InetAddress.getByName("255.255.255.255");
} catch (UnknownHostException e) {
e.printStackTrace();
}
int msg_length = message.length();
byte[] messageByte = message.getBytes();
DatagramPacket p = new DatagramPacket(messageByte, msg_length, local,
server_port);
try {

s.send(p);
s.close();

} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void run() {
StartListen();
}
}

希望能帮到你。

2. android:udp广播

首先手机作为终端 可以不必要知道终端的数量、 还有就是我建议你多学习下基础,android的广播机制不是把广播在终端之间传输,广播是在应用程序里面发送,在应用程序进行接收。个人建议基础才是王道。 对于你现在这个问题,不妨采用发送消息的方式 实现该功能。一个终端发送消息 其他终端接收消息,当然也相当于写一个socket通信。通信建立之后 ,可以取得各个连接的终端的IP 然后怎么逻辑就看你怎么写算法了。还有就是,这个功能也可以用消息推送的方式(建议采用此方法)、android系统内置有消息推送,逻辑都和上述的差不多,至于具体用那些方法 那些内置类,个人建议多查API。软件开发必须靠自学。。。。

3. (三)Android局域网内语音对讲 基于UDP语音传输

之前研究了基于UDP的文字传输 点击打开链接 ,以及Android端的语音录制 点击打开链接 ,这篇文章就记录一下Android端局域网内的语音传输,简单的实现语音对讲,当然里面还存在着很多问题,包括语音不清晰啊、杂音多啊,不管了,先听见声音就行了。测试的时候两部手机,上图:

程序写了两个线程,一个用于录制AudioRecordThread,一个用于播放AudioTrackThread.

(一)录制与发送

@Override

public void run() {

if (mSocket == null)

return;

try {

mStartTime = System.currentTimeMillis();

audioRec.startRecording();

while (flag) {

try {

byte[] bytes_pkg = buffer.clone();

if (mRecordQueue.size() >= 2) {

int length = audioRec.read(buffer, 0, minBufferSize);

//获取音量大小

mVolume = getAudioColum(buffer);

System.out.println(TAG + "= " + mVolume);

Message message = mHandler.obtainMessage();

message.arg1 = (int) mVolume;

mHandler.sendMessage(message);

DatagramPacket writePacket;

InetAddress inet = InetAddress.getByName(inetAddressName);

writePacket = new DatagramPacket(buffer, length, inet, PORT);

writePacket.setLength(length);

System.out.println("AudioRTwritePacket = " + writePacket.getData().toString());

mSocket.send(writePacket);

}

mRecordQueue.add(bytes_pkg);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

audioRec.stop();

} catch (Exception e) {

e.printStackTrace();

}

}

里面包含了获取音量大小,便于在页面上面展示,方法参考了 点击打开链接

private double getAudioColum(byte[] buffer) {

double sumVolume = 0.0;

double avgVolume = 0.0;

double volume = 0.0;

for (int i = 0; i < buffer.length; i += 2) {

int v1 = buffer[i] & 0xFF;

int v2 = buffer[i + 1] & 0xFF;

int temp = v1 + (v2 << 8);// 小端

if (temp >= 0x8000) {

temp = 0xffff - temp;

}

sumVolume += Math.abs(temp);

}

avgVolume = sumVolume / buffer.length / 2;

volume = Math.log10(1 + avgVolume) * 10;

return volume;

}

(二)接收与播放

@Override

public void run() {

if (mSocket == null)

return;

//从文件流读数据

audioTrk.play();

while (flag) {

DatagramPacket recevPacket;

try {

recevPacket = new DatagramPacket(buffer, 0, buffer.length);

mSocket.receive(recevPacket);

audioTrk.write(recevPacket.getData(), 0, recevPacket.getLength());

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

audioTrk.stop();

}

(三)主页面 接收按钮事件

@OnClick({R.id.btn_receive})

public void onViewClicked(View view) {

switch (view.getId()) {

case R.id.btn_receive:

if (btnReceive.getText().toString().equals("开始接收")) {

btnReceive.setText("停止接收");

try {

if (audioTrackThread == null) {

audioTrackThread = new AudioTrackThread();

}

new Thread(audioTrackThread).start();

} catch (SocketException e) {

e.printStackTrace();

}

} else {

btnReceive.setText("开始接收");

audioTrackThread.setFlag(false);

}

break;

}

}

(四)发送按钮事件

ivSpeak.setOnTouchListener(new View.OnTouchListener() {

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)

@Override

public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

//按下按钮开始录制

ivSpeak.setText("正在说话");

//显示录音提示

relativeLayout.setVisibility(View.VISIBLE);

try {

if (audioRecordThread == null) {

audioRecordThread = new AudioRecordThread(handler);

}

audioRecordThread.setInetAddressName(tvReceiveIp.getText().toString());

audioRecordThread.setFlag(true);

new Thread(audioRecordThread).start();

} catch (SocketException e) {

e.printStackTrace();

}

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

//松开按钮结束录制

ivSpeak.setText("按住说话");

relativeLayout.setVisibility(View.GONE);

audioRecordThread.setFlag(false);

mStopTime = audioRecordThread.getmStopTime();

mStartTime = audioRecordThread.getmStartTime();

creatMessageBean((mStopTime - mStartTime) / 1000, true);

break;

}

return true;

}

});

4. Android UDP通讯(简单demo)

本章节 比较简单
直接上code了
首先创建一个UDP class 构造方法如下
通过newFixedThreadPool 创建一个线程池

然后
一个startUdp scoket 重要步骤

startSocketThread是一个 接收消息的子线程
内部是一个接收消息的循环
BROADCAST_IP 是通信对方的地址

利用广播 把接收到的消息打印到前台

再然后创建一个发送message的方法

文章所有code 地址---> github
https://github.com/hanjole/Udpscoket_demo

5. android 如何定时发udp

定时执行任务可以考虑使用AlarmManager配合BroadcastReceiver实现
AlarmManager定时发出intent,BroadCastReceiver收到这个intent后进行发送UDP的操作

6. Android 手机上能通过DatagramSocket收到PC端的UDP广播吗

在PC端直接用tcp调试助手发送数据,我另一台电脑能收到的,但是android的却是有时可以收到有时收不到,平均几十次收到10次左右,丢包不可能这么严重吧。,android的代码如下,
ds = new DatagramSocket(1234, InetAddress.getByName(“192.168.1.3”));
dp = new DatagramPacket(content, content.length);
ds.receive(dp);
如果我在pc端发送绑定了IP的UDP数据包,android可以收到数据,但是PC端发送255的广播UDP,android就收不到了。。查了一些资料,说是要加入权限,加入以下的代码,但实测发现效果一样。

WifiManager manager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); WifiManager.MulticastLock lock= manager.createMulticastLock("localWifi");

7. (四)Android基于UDP的多客户端语音通信

在前三篇得基础上,这次研究了组播功能。非常感谢https://blog.csdn.net/jspping/article/details/64438515得贡献!

组播也就是通过MulticastSocket来进行开发,与DatagramSocket比较相类似,这次依然是用两个线程进行实现,发送线程MultiSendThread和接收线程MultiReceiveThread。废话不多说,开始码:

(一)MultiSendThread:

(1)初始化MuticastSocket

// 侦听的端口

try {

    multicastSocket = new MulticastSocket(8082);

    // 使用D类地址,该地址为发起组播的那个ip段,即侦听10001的套接字

    address = InetAddress.getByName("239.0.0.1");

} catch (IOException e) {

    e.printStackTrace();

}

(2)初始化AudioRecord

protected LinkedList<byte[]> mRecordQueue;

int minBufferSize;

private static AcousticEchoCanceler aec;

private static AutomaticGainControl agc;

private static NoiseSuppressor nc;

AudioRecord audioRec;

byte[] buffer;

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)

private void initAudio() {

    //播放的采样频率 和录制的采样频率一样

    int sampleRate = 44100;

    //和录制的一样的

    int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

    //录音用输入单声道  播放用输出单声道

    int channelConfig = AudioFormat.CHANNEL_IN_MONO;

    minBufferSize = AudioRecord.getMinBufferSize(

            sampleRate,

            channelConfig, AudioFormat.ENCODING_PCM_16BIT);

    System.out.println("****RecordMinBufferSize = " + minBufferSize);

    audioRec = new AudioRecord(

            MediaRecorder.AudioSource.MIC,

            sampleRate,

            channelConfig,

            audioFormat,

            minBufferSize);

    buffer = new byte[minBufferSize];

    if (audioRec == null) {

        return;

    }

    //声学回声消除器 AcousticEchoCanceler 消除了从远程捕捉到音频信号上的信号的作用

    if (AcousticEchoCanceler.isAvailable()) {

        aec = AcousticEchoCanceler.create(audioRec.getAudioSessionId());

        if (aec != null) {

            aec.setEnabled(true);

        }

    }

    //自动增益控制 AutomaticGainControl 自动恢复正常捕获的信号输出

    if (AutomaticGainControl.isAvailable()) {

        agc = AutomaticGainControl.create(audioRec.getAudioSessionId());

        if (agc != null) {

            agc.setEnabled(true);

        }

    }

    //噪声抑制器 NoiseSuppressor 可以消除被捕获信号的背景噪音

    if (NoiseSuppressor.isAvailable()) {

        nc = NoiseSuppressor.create(audioRec.getAudioSessionId());

        if (nc != null) {

            nc.setEnabled(true);

        }

    }

    mRecordQueue = new LinkedList<byte[]>();

}

(3)开始录制,并实时发送出去

@Override

public void run() {

    if (multicastSocket == null)

        return;

    try {

        audioRec.startRecording();

        while (true) {

            try {

                byte[] bytes_pkg = buffer.clone();

                if (mRecordQueue.size() >= 2) {

                    int length = audioRec.read(buffer, 0, minBufferSize);

                    // 组报

                    DatagramPacket datagramPacket = new DatagramPacket(buffer, length);

                    // 向组播ID,即接收group /239.0.0.1  端口 10001

                    datagramPacket.setAddress(address);

                    // 发送的端口号

                    datagramPacket.setPort(10001);

                    System.out.println("AudioRTwritePacket = " + datagramPacket.getData().toString());

                    multicastSocket.send(datagramPacket);

                }

                mRecordQueue.add(bytes_pkg);

            } catch (Exception e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

    } catch (Exception e) {

        e.printStackTrace();

    }

}

(二)MultiReceiveThread

(1)初始化MulticastSocket

// 接收数据时需要指定监听的端口号

try {

    multicastSocket = new MulticastSocket(10001);

    // 创建组播ID地址

    InetAddress address = InetAddress.getByName("239.0.0.1");

    // 加入地址

    multicastSocket.joinGroup(address);

} catch (IOException e) {

    e.printStackTrace();

}

(2)初始化AudioTrack

byte[] buffer;

AudioTrack audioTrk;

private void initAudioTracker() {

    //扬声器播放

    int streamType = AudioManager.STREAM_MUSIC;

    //播放的采样频率 和录制的采样频率一样

    int sampleRate = 44100;

    //和录制的一样的

    int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

    //流模式

    int mode = AudioTrack.MODE_STREAM;

    //录音用输入单声道  播放用输出单声道

    int channelConfig = AudioFormat.CHANNEL_OUT_MONO;

    int recBufSize = AudioTrack.getMinBufferSize(

            sampleRate,

            channelConfig,

            audioFormat);

    System.out.println("****playRecBufSize = " + recBufSize);

    audioTrk = new AudioTrack(

            streamType,

            sampleRate,

            channelConfig,

            audioFormat,

            recBufSize,

            mode);

    audioTrk.setStereoVolume(AudioTrack.getMaxVolume(),

            AudioTrack.getMaxVolume());

    buffer = new byte[recBufSize];

}

(3)开始接收,并进行实时播放

@Override

public void run() {

    if (multicastSocket == null)

        return;

    //从文件流读数据

    audioTrk.play();

    // 包长

    while (true) {

        try {

            // 数据报

            DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length);

            // 接收数据,同样会进入阻塞状态

            multicastSocket.receive(datagramPacket);

          audioTrk.write(datagramPacket.getData(), 0, datagramPacket.getLength());

        } catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

}

(三)开始测试

MultiSendThread multiSendThread;

MultiReceiverThread multiReceiverThread;

@OnClick({R.id.btnSend, R.id.btnReceive})

public void onViewClicked(View view) {

    switch (view.getId()) {

        case R.id.btnSend:

            if (multiSendThread == null) {

                multiSendThread = new MultiSendThread();

            }

            new Thread(multiSendThread).start();

            break;

        case R.id.btnReceive:

            if (multiReceiverThread == null) {

                multiReceiverThread = new MultiReceiverThread();

            }

            new Thread(multiReceiverThread).start();

            break;

    }

}

8. android接收不到udp包吗

1、有的手机不能直接接收UDP包,可能是手机厂商在定制Rom的时候把这个功能给关掉了。
2、在UDP通信中,android端发送UDP广播包没有问题。至于接收的话,有时候不能接收到包。

9. Android 使用udp发送广播

最近做项目时,遇到一个对新人我来说稍微有点麻烦的事情!

那就是使用udp协议发送广播获取服务器地址

http都好说,github开源项目不知道有多少。

可是再难的问题也要去解决!

发送广播需要权限!

AndroidManifest.xml 中添加:

最少这三个是必须的,多的也忘了!
原因后面会讲到

使用到RxJava:

udp发送与接受都需指定端口号
广播地址是255.255.255.255

在之前添加权限的时候CHANGE_WIFI_MULTICAST_STATE有添加这个
往下面看

接下来我们开启接收udp信息

发送消息?

谢谢该作者的文章让我学会udp发送
https://blog.csdn.net/tanghongchang123/article/details/53609237

10. Android 基于UDP的Socket通信

1、连接DatagramSocket的服务端(ip和port):开启异步线程和socket
2、发送数据(DatagramPacket):异步
3、接收数据(DatagramPacket):注意连接状态,异步读取
4、关闭连接:关闭DatagramSocket和对应线程

1、异常:android.os.NetworkOnMainThreadException。 socket需要在线程中使用
2、前后端统一传输或者接收协议 [requestcode size d1 d2 d3 ... ],在解析时候用得到
3、实施监控socket的连接状态,还是用心跳包发过去,然后返回数据,一段时间没有的话则代表socket连接失败。
4、注意receive接收数据后的有效长度(一个是预存的buffer,一个是有效结果buffer)
5、客户端连上去后不知道为何一定要先发送一次,才能接收?
6、UDP不安全,有长度限制64K

2019 (* ̄(oo) ̄) 诸事顺利!

阅读全文

与android发送udp广播相关的资料

热点内容
云视讯注册状态服务器错误801 浏览:852
python中删除csv 浏览:591
oracle创建表空间命令 浏览:14
十块钱五分钟的解压人偶 浏览:934
学android看什么书 浏览:376
网络加密了手机上怎样显示 浏览:805
文章被以什么形式存放在服务器中 浏览:708
炮兵命令 浏览:116
网商园app怎么样啊 浏览:325
app字体大小怎么设置在哪 浏览:432
华为app选择网络模式哪里找 浏览:321
策划优化服务器是什么 浏览:238
联想的组织服务器怎么连接 浏览:218
程序员千里贵州头条 浏览:672
阿里云服务器199一年 浏览:688
支点app里面有币怎么办 浏览:65
程序员ps 浏览:720
滴滴app顺风车怎么更换车辆信息 浏览:22
胡莱三国怎么更换服务器 浏览:816
木解压神器中的钢琴弹出儿童歌曲 浏览:530