前言

  • UDP是无连接协议,即是在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来讲,当一台计算机向另一台计算机发送数据时,发送端不会决定接收方存不存在,就会发出数据,同样接受端在收到数据时,也不会向发送端反馈是否接到数据。
  • 本文基于同一局域网下设备交互场景讲解。
  • udp本身没有c/s的概念,为了方便区分为客户端和服务端。
  • 在android中发送和接收消息都需要在子线程中操作。

发送消息

  • 为了保证消息发送成功,规定了服务端接收到消息必须给返回响应数据
  • TIMEOUT设置发送消息后等待响应的时间,RETRY_NUM设置重发的次数。
    /*** 发送udp消息** @param ip       ip地址* @param port     端口* @param data     数据* @param callback 响应数据回调*/public static void sendMessage(String ip, int port, String data, UDPCallback callback) {mPool.execute(() -> {try {InetAddress inetAddress = InetAddress.getByName(ip);DatagramSocket client = new DatagramSocket();// 设置接收数据时阻塞的最长时间client.setSoTimeout(TIMEOUT);// 发送数据包byte[] dataBytes = data.getBytes();DatagramPacket dataPacket = new DatagramPacket(dataBytes, dataBytes.length, inetAddress, port);// 响应数据包byte[] responseBytes = new byte[1024 * 1024];DatagramPacket responsePacket = new DatagramPacket(responseBytes, responseBytes.length);int tries = 0;boolean receivedResponse = false;while (!receivedResponse && tries < RETRY_NUM) {// 发送数据client.send(dataPacket);try {// 响应数据client.receive(responsePacket);String serviceIp = responsePacket.getAddress().getHostAddress();String response = new String(responseBytes, 0, responsePacket.getLength());if (callback != null) {ThreadUtils.runOnUiThread(() -> callback.call(serviceIp, response));}receivedResponse = true;} catch (InterruptedIOException e) {// 如果接收数据时阻塞超时,重发并减少一次重发的次数tries += 1;Log.e("udp", "client Time out," + (RETRY_NUM - tries) + " more tries...");}}Log.e("udp", "client No response -- give up.");client.close();} catch (IOException e) {e.printStackTrace();}});}

接收消息

  • 接收消息receive方法是阻塞的,控制死循环一直接收消息
    /*** 接收udp消息** @param port     端口* @param repeat   重复接收* @param response 响应数据* @param callback 接收数据回调*/public static void receiveMessage(int port, boolean repeat, String response, UDPCallback callback) {isReceiveRunning = true;mPool.execute(() -> {try {// 接收数据byte[] dataBytes = new byte[1024 * 1024];final DatagramPacket clientPacket = new DatagramPacket(dataBytes, dataBytes.length);DatagramSocket service = new DatagramSocket(null);service.setReuseAddress(true);service.bind(new InetSocketAddress(port));do {service.receive(clientPacket);String clientIp = clientPacket.getAddress().getHostAddress();String data = new String(dataBytes, 0, clientPacket.getLength());ThreadUtils.runOnUiThread(() -> callback.call(clientIp, data));// 响应数据byte[] responseBytes = (response == null ? "default response" : response).getBytes();DatagramPacket responsePacket = new DatagramPacket(responseBytes, responseBytes.length, clientPacket.getAddress(), clientPacket.getPort());service.send(responsePacket);} while (repeat && isReceiveRunning);service.disconnect();service.close();} catch (IOException e) {e.printStackTrace();}});}

建立连接

  • 建立连接逻辑是客户端和服务端绑定不同的端口,客户端发送广播到指定的服务端端口,服务端接收广播发送的消息并响应,双方获取到对应的IP以实现一对一的发送。
    /*** 重复发送udp广播** @param port     端口* @param data     数据* @param interval 间隔时间* @param callback 响应回调*/public static void sendBroadcast(int port, String data, int interval, UDPCallback callback) {isSendBroadcastRunning = true;Runnable runnable = new Runnable() {@Overridepublic void run() {sendMessage(NetworkUtils.getBroadcastIpAddress(), port, data, callback);if (isSendBroadcastRunning) {mHandler.postDelayed(this, interval);}}};mHandler.postDelayed(runnable, interval);}/*** 发送udp广播** @param port     端口* @param data     数据* @param callback 响应回调*/public static void sendBroadcast(int port, String data, UDPCallback callback) {sendMessage(NetworkUtils.getBroadcastIpAddress(), port, data, callback);}

示例

https://gitee.com/mayuzyb/sample-code/tree/master/Socket

android socket-udp通信相关推荐

  1. bs结构socket(udp)通信

    以前我所做的基于socket通信都是采用cs结构,现公司有一个项目需要在bs中反控设备,于是研究了一番,现将成果公布,方便以后查阅. 服务端: #region udpint recv;byte[] d ...

  2. Python多人聊天室-基于socket UDP协议

    简介 使用Python编写的基于socket UDP通信的多功能即时聊天室,包含Tkinter编写的图形化聊天界面,功能包括有账号注册和登录,登录成功后可以查看在线用户,并和聊天室内的其他在线用户聊天 ...

  3. 【Android开发—智能家居系列】(四):UDP通信发送指令

    思路回顾 [1]手机连接WIFI模块 [2]UDP通信对WIFI模块发送指令,以和WIFI模块保持连接状态 [3]UDP通信对WIFI模块发送指令,让其搜索可用的无线网,返回WIFI列表 [4]发送指 ...

  4. java安卓模拟器和电脑通信_PC电脑和Android模拟器访问及模拟器之间tcp/udp通信

    Android系统默认只能通过IP(10.0.2.2)单向访问PC电脑,而PC电脑不能通过IP来直接访问Android模拟器系统.要想实现PC电脑和Android模拟器系统以及Android模拟器之间 ...

  5. android模拟器与pc,模拟器与模拟之间用socket进行通信和获得模拟器ip地址程序

    一.PC电脑和Android模拟器访问及模拟器之间tcp/udp通信 http://orgcent.com/pc-android-emulator-socket/ Android系统默认只能通过IP( ...

  6. android传递socket对象,Android Socket通信详解

    一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时 ...

  7. Android开发使用ServerSocket ServerSocketChannel DatagramSocket进行TCP UDP通信 实现服务器与APP消息推送

    前言 在日常开发中采用Http协议进行数据传输的情况非常多,但这都是APP主动请求服务端,将数据传到服务器或者从服务器下载数据:那么如果我们想服务器主动联系我们或者我们频繁的上报消息给服务器,怎么弄呢 ...

  8. Android Socket通信(五) -- 实现一个多人聊天室

    系列文章: Android Socket 系列更新计划 Android Socket通信(一) – 初识与相遇 Android Socket通信(二) --UDP,单播,广播和多播(组播) Andro ...

  9. Android Wifi连接控制、TCP、UDP通信,6.0以上适配

    本文章包含内容 Wifi连接控制.Wifi广播接收,适配了Android6.0以上的版本 Wifi下的TCP通信 Wifi下的UDP通信 Github项目地址 码云项目地址 最近公司要开发智能家居,A ...

  10. Qt使用UDp通信、套接字socket的成员函数bind()的作用

    一. 所谓bind,就是指绑定本地接受端口.          指定ip,是为了分辨多ip主机.在有服务端和客户端的UDP中,bind是服务端调用的函数,绑定的是服务端的IP,假设服务端有多个网卡,即 ...

最新文章

  1. Android UI开发第五篇——自定义列表
  2. Python最简编码规范
  3. Xamarin.Forms教程下载安装Visual Studio 2015
  4. 比特币交易平台 php,比特币PHP离线交易开发包
  5. iOS程序启动过程笔记
  6. epoll 接口以及原理说明
  7. Ubuntu 12.04 如何切换回英文
  8. react大数据量渲染_UseEffect在React中运行无限渲染(超过最大更新深度)
  9. 最快的存储过程分页 50W
  10. c语言复杂数据类型存储,C语言基础-复杂数据类型
  11. 工作总结 项目中如何处理重复提交问题
  12. 使用MTL库求解矩阵特征值和特征向量
  13. 卡巴斯基6.0离线升级包的制作和使用方法
  14. Unity Asset Store——独立游戏开发者的素材插件商店
  15. 字符编码-- Unicode(1991年)
  16. supermicro board bios 升级 超微主板刷 bios
  17. python实现:无刻度的一大一小水罐取水问题
  18. 柴静穹顶之下 感想
  19. 启动计算机实现5秒开机,电脑3秒开机,怎么做到的?
  20. 12.2 两个重要级数

热门文章

  1. A Blockchain-Based Machine Learning Framework for Edge Services in IIoT 论文学习
  2. 雨中重装徒步攀登清凉峰
  3. NVlabs/noise2noise代码(一)概览与运行
  4. python 求导实现_python怎么实现函数求导
  5. Quest 3d中Lua script中常用方法1
  6. 高分2号遥感影像数据融合
  7. POJ2828 Buy Tickeys 树状数组+二分 线段树留坑。。。
  8. 双工位机器人 焊接夹具注意事项 o(╯□╰)o
  9. UNP学习笔记-第三章套接字编程
  10. 西湖大学遭质疑,多是“天坑”专业?校长施一公“霸气”回应