【Android Socket专题】:UDP通信客户端app的demo的实现

2023-11-13

Android Socket 专题:

UDP Client客户端  http://blog.csdn.net/shankezh/article/details/50731287

UDP Server服务器 http://blog.csdn.net/shankezh/article/details/51452811

TCP Client客户端  http://blog.csdn.net/shankezh/article/details/70763579

TCP Server服务器 http://blog.csdn.net/shankezh/article/details/51555455

关于UDP通信其实可以不用多做累述,多数像我一样的朋友在此基础上也只是为了应用,需要了解下该了解的就可以了,具体的想要对这个协议研究深入的,可以自己努力!我这儿只做Android客户端的应用实现,注意是客户端,不是服务器,那么服务器怎么实现呢? 点击上方,已经补充!!!


规划自己的界面的(非常简单):

XML实现效果图如下:

附上对应XML代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:layout_weight="2"
    tools:context="jiugaosh.com.udpdemo.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="vertical"
        android:layout_weight="1">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="接收区:" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="right"
                android:textSize="8dp"
                android:id="@+id/btn_udpConn"
                android:text="建立连接" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="right"
                android:textSize="8dp"
                android:id="@+id/btn_udpClose"
                android:text="关闭连接" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="right"
                android:textSize="8dp"
                android:id="@+id/btn_CleanRecv"
                android:text="清除接收区" />
        </LinearLayout>

        <TextView
            android:layout_width="match_parent"
            android:layout_weight="7"
            android:layout_height="0dp"
            android:id="@+id/txt_Recv"
            android:background="@drawable/border"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:orientation="horizontal"
            android:layout_weight="2">
            <CheckBox
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:text="Hex显示"/>
            <CheckBox
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"

                android:text="二进制显示"/>
            <CheckBox
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:text="十进制显示"/>

        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="vertical"
        android:layout_weight="1">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:text="发送区:" />
        <TextView
            android:layout_width="match_parent"
            android:layout_weight="7"
            android:background="@drawable/border"
            android:id="@+id/txt_Send"
            android:layout_height="0dp" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:orientation="horizontal"
            android:layout_weight="2">
            <CheckBox
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:text="Hex显示"/>
            <CheckBox
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"

                android:text="二进制显示"/>
            <CheckBox
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:text="十进制显示"/>

        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:orientation="horizontal"
            android:layout_weight="2">
            <EditText
                android:layout_width="0dp"
                android:layout_weight="5"
                android:id="@+id/edit_Send"
                android:background="@drawable/border"
                android:layout_height="match_parent" />
            <Button
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent"
                android:layout_gravity="right"
                android:id="@+id/btn_Send"
                android:text="发送"/>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

至此我们界面全部完成,我们开始实现对应功能!继续向下看。

首先在写代码前要说明下关键性的几个类,我们完成udp客户端其实主要就是通过这几个类实现的:

1、DatagramSocket

2、DatagramPacket 

3、InetAddress

关于这几个类到底是什么意思,包含了什么信息,大家可以自己去百度谷歌,或者直接打开JAVA API文档查看便知,这里不做赘述,看具体实现。

关于UDP客户端收发这里,实现思路是:

启动UDP线程:

1、创建DatagramSocket通信数据报

2、建立接收事件专用DatagramPacket数据包

3、创建超时(这个和后面关闭通信有关)

4、建立监听接收消息循环机制(接收消息处理在此处,接收到的消息通过BroadcastReceiver发送给主界面)

5、结束循环,关闭数据报。

以上为收取信息思路,发送信息则为UDP线程中的一个方法,直接被调用,共享了接收块的DatagramSocket数据报:

UDP Thread Run--->[Function方法]send(String SendMsg)


下面看具体代码实现:

package jiugaosh.com.udpdemo;

import android.content.Intent;
import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

/**
 * Created by lenovo on 2016/2/23.
 */
public class UDPClient implements Runnable{
    final static int udpPort = 9999;
    final static String hostIp = "192.168.1.4";
    private static DatagramSocket socket = null;
    private static DatagramPacket packetSend,packetRcv;
    private boolean udpLife = true; //udp生命线程
    private byte[] msgRcv = new byte[1024]; //接收消息

    public UDPClient(){
        super();
    }

    //返回udp生命线程因子是否存活
    public boolean isUdpLife(){
        if (udpLife){
            return true;
        }

        return false;
    }

    //更改UDP生命线程因子
    public void setUdpLife(boolean b){
        udpLife = b;
    }

    //发送消息
    public String send(String msgSend){
        InetAddress hostAddress = null;

        try {
            hostAddress = InetAddress.getByName(hostIp);
        } catch (UnknownHostException e) {
            Log.i("udpClient","未找到服务器");
            e.printStackTrace();
        }

/*        try {
            socket = new DatagramSocket();
        } catch (SocketException e) {
            Log.i("udpClient","建立发送数据报失败");
            e.printStackTrace();
        }*/

         packetSend = new DatagramPacket(msgSend.getBytes() , msgSend.getBytes().length,hostAddress,udpPort);

        try {
            socket.send(packetSend);
        } catch (IOException e) {
            e.printStackTrace();
            Log.i("udpClient","发送失败");
        }
     //   socket.close();
        return msgSend;
    }

    @Override
    public void run() {

        try {
            socket = new DatagramSocket();
            socket.setSoTimeout(3000);//设置超时为3s
        } catch (SocketException e) {
            Log.i("udpClient","建立接收数据报失败");
            e.printStackTrace();
        }
        packetRcv = new DatagramPacket(msgRcv,msgRcv.length);
        while (udpLife){
            try {
                Log.i("udpClient", "UDP监听");
                socket.receive(packetRcv);
                String RcvMsg = new String(packetRcv.getData(),packetRcv.getOffset(),packetRcv.getLength());
                //将收到的消息发给主界面
                Intent RcvIntent = new Intent();
                RcvIntent.setAction("udpRcvMsg");
                RcvIntent.putExtra("udpRcvMsg", RcvMsg);
                MainActivity.context.sendBroadcast(RcvIntent);

                Log.i("Rcv",RcvMsg);
            }catch (IOException e){
                e.printStackTrace();
            }
        }

        Log.i("udpClient","UDP监听关闭");
        socket.close();
    }
}

至此UDP核心代码全部部署完成,其中包含了少许其他功能, 如发送给主界面消息代码等,不影响,有不需要的可以自行删除。其中如果想发送消息,那么调用其中的send方法即可。

下面则是主界面代码实现,我的实现思路如下(各有各的实现方法,如果您有更好的,如果愿意请告诉我,我十分愿意学习):

MainActivity界面:

Handler类(主要处理UI更新事件)

OnCreate(绑定控件,事件监听,注册BroadcastReceiver等)

MyButtonClick类(处理各按钮事件)

BroadcastReceiver(广播接收器)

至于里面各自类包含的小逻辑,就不多讲了,看demo可以很快便知道如何使用对应了。


话不多说,放码过来:

package jiugaosh.com.udpdemo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Message;
import android.support.v7.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 android.os.Handler;

import java.lang.ref.WeakReference;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class MainActivity extends AppCompatActivity {
    TextView txt_Recv,txt_Send;
    Button   btn_CleanRecv,btn_Send,btn_UdpConn,btn_UdpClose;
    EditText edit_Send;
    private UDPClient client = null;
    public static Context context;
    private final MyHandler myHandler = new MyHandler(this);
    private StringBuffer udpRcvStrBuf=new StringBuffer(),udpSendStrBuf=new StringBuffer();



    MyBtnClick myBtnClick = new MyBtnClick();


    private class MyHandler extends Handler{
        private final WeakReference<MainActivity> mActivity;
        public MyHandler(MainActivity activity){
            mActivity = new WeakReference<MainActivity>(activity);
        }
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 1:
                    udpRcvStrBuf.append(msg.obj.toString());
                    txt_Recv.setText(udpRcvStrBuf.toString());
                    break;
                case 2:
                    udpSendStrBuf.append(msg.obj.toString());
                    txt_Send.setText(udpSendStrBuf.toString());
                    break;
                case 3:
                    txt_Recv.setText(udpRcvStrBuf.toString());
                    break;
            }
        }
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;
        bindWidget();   //控件绑定
        listening();    //监听事件
        bindReceiver();//注册broadcastReceiver接收器
        iniWidget();    //初始化控件状态
    }

    private void bindWidget(){
        txt_Recv = (TextView)findViewById(R.id.txt_Recv);
        txt_Send = (TextView)findViewById(R.id.txt_Send);
        btn_CleanRecv = (Button)findViewById(R.id.btn_CleanRecv);
        btn_Send = (Button)findViewById(R.id.btn_Send);
        btn_UdpConn = (Button)findViewById(R.id.btn_udpConn);
        btn_UdpClose = (Button)findViewById(R.id.btn_udpClose);
        edit_Send = (EditText)findViewById(R.id.edit_Send);
    }

    private void listening(){
        btn_Send.setOnClickListener(myBtnClick);
        btn_UdpConn.setOnClickListener(myBtnClick);
        btn_UdpClose.setOnClickListener(myBtnClick);
        btn_CleanRecv.setOnClickListener(myBtnClick);
    }

    private void bindReceiver(){
        IntentFilter udpRcvIntentFilter = new IntentFilter("udpRcvMsg");
        registerReceiver(broadcastReceiver,udpRcvIntentFilter);
    }

    private void iniWidget(){
        btn_Send.setEnabled(false);
    }

    class MyBtnClick implements Button.OnClickListener{

        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btn_CleanRecv:
                    udpRcvStrBuf.delete(0,udpRcvStrBuf.length());
                    Message message = new Message();
                    message.what = 3;
                    myHandler.sendMessage(message);
                    break;
                case R.id.btn_udpConn:
                    //建立线程池
                    ExecutorService exec = Executors.newCachedThreadPool();
                    client = new UDPClient();
                    exec.execute(client);
                    btn_UdpClose.setEnabled(true);
                    btn_UdpConn.setEnabled(false);
                    btn_Send.setEnabled(true);
                    break;
                case R.id.btn_udpClose:
                    client.setUdpLife(false);
                    btn_UdpConn.setEnabled(true);
                    btn_UdpClose.setEnabled(false);
                    btn_Send.setEnabled(false);
                    break;
                case R.id.btn_Send:
                    Thread thread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Message message = new Message();
                            message.what = 2;
                            if (edit_Send.getText().toString()!=""){
                                client.send(edit_Send.getText().toString());
                                message.obj = edit_Send.getText().toString();
                                myHandler.sendMessage(message);
                            }
                            
                        }
                    });
                    thread.start();
                    break;
            }
        }
    }

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.hasExtra("udpRcvMsg"))  {
                Message message = new Message();
                message.obj = intent.getStringExtra("udpRcvMsg");
                message.what = 1;
                Log.i("主界面Broadcast","收到"+message.obj.toString());
                myHandler.sendMessage(message);
            }
        }
    };


}
当然,不能忘记在AndroidMainFest文件中加上权限,毕竟你是要联网的!
<uses-permission android:name="android.permission.INTERNET" />


写在最后:实现这些功能其实较为简单,网上有很多成熟且很棒的例子,各位多看多学,必没有问题!其中进制转换其实很简单实现,各位只要对那两个stringbuffer进行进制操作和显示即可!


通信效果请点击上方UDP server最后有图片展示


附上demo:

http://download.csdn.net/detail/shankezh/9442049


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Android Socket专题】:UDP通信客户端app的demo的实现 的相关文章

随机推荐

  • 解决IDEA2019.1.3无法创建包的子类包问题

    有时候我们需要创建包的子类包 空包 的时候我们发现 不知道如何在初始的包中创建子类包 随后在别的博客上看了好多解决方法 好多都是没有选中父类包 或者没有将下面这个选项勾掉 但是这个勾掉的话就把父类中最后一个包也变成了子类包 并没有达到我们所
  • “先裁掉女员工!”

    身为女性在职场 不得不面对一些尴尬的时刻 我朋友公司刚招了一个商务的妹纸 没几周就说自己怀孕了 紧接着 开启了三天打鱼两天晒网的请假模式 今年就业环境不太理想 朋友公司招人有严格的名额限制 考虑再三 上司和HR昨天找她面谈 上司说 市场岗压
  • leveldb 源码--总体架构分析

    一 本文目的 对leveldb的总体设计框架分析 关于leveldb基本原理 此文不做阐述 读者可以自行检索文章阅读即可 对leveldb中底层数据存储数据格式 内存数据模型 compact 版本管理 快照等机制实现介绍以及整个leveld
  • 弯道超车,阿里高工新产Java面试速成指南,面试骚操作都在里面了

    金三银四过去一半 市场火热 但是大家就业压力却没有缓解多少 很多粉丝后台留言 Java程序员面临的竞争太激烈了 我自己也有实感 多年身处一线互联网公司 虽没有直面过求职跳槽的残酷 但经常担任技术面试考官 对程序员招聘市场的现状很清楚 导致现
  • C++中.cpp和.hpp的区别

    时间 2020 06 02 标签 c cpp hpp 区别 栏目 C C 繁體版 原文 https my oschina net u 4398200 blog 3336507 原文地址 https blog csdn net qzx9059
  • H5中写一个下拉框,点击下拉框内容会出现在文本域中

    朋友出去面试做的面试题 分享了下 我就拿来做做 原题 HTML中有个下拉框 包含 风 雨 雷 电 添加事件 当选择风时 文本域内出现选择
  • 使用proteus仿真集成运放构成的三角波发生电路

    仿真电路图 仿真示波器结果
  • 用python做小游戏——以弹球游戏为例

    本博客使用了Pygame库来创建游戏窗口和处理游戏逻辑 一 代码详细解释 首先 通过调用pygame init 来初始化Pygame库 然后创建一个窗口并设置标题 pygame init screen pygame display set
  • 当全景视频遇到快手

    收到 山巅之处 正午的阳光透过翻滚的云海铺洒在岩石壁上 镶嵌在天边连绵起伏的山峦若隐若现 雄伟壮观 俯瞰去 脚下是天梯般陡峭的山崖 连接着山中绿洲 纵身一跃 映入眼帘的是逐渐清晰的林海 那些拔地而起的树木紧密相连 铸成一座郁郁葱葱的 绿色长
  • docker容器内服务访问宿主机服务

    我的个人博客 逐步前行STEP 本文背景 操作系统 macOs 笔者的docker虚拟机中运行了nginx node服务用来部署一个前后端分离的网站 但是由于docker内的node服务运行效率极低 每次代码更新后也不会自动重新编译 所以准
  • 函数间隔和几何间隔

    问题描述 求一个任意点 到一个超平面的距离 超平面表示 在线性代数中 一个超平面可以用下式表示 y X W T
  • 借助ChatGPT自动生成PPT

    借助ChatGPT自动生成PPT 首先让GPT生成一段markdown格式的PPT内容 尽量描述全面 以什么语言 什么格式 排版等等 打开mindshow网址 点击import and create 选择以markdown方式创建 再次点击
  • c++: 实战详解vector

    目的 本文从实际使用的角度出发 简介C 中vector的基本用法 如增 删 改 查等 并举例说明 增 如下代码演示如何向vector中添加元素 其中 include
  • NotePad++添加到右键快捷方式

    首先看效果图 NotePad 添加到右键快捷方式 接下来是操作方式 首先在桌面上新建一个txt文本文档 然后将写入如下内容 Windows Registry Editor Version 5 00 HKEY CLASSES ROOT she
  • 人才梯队如何搭建,3个维度让你打造一支人才团队

    模型在手 方法我有 文末完整版 一 人才梯队可以不建立吗 二 人才梯队建设的目的 三 梯队人才的培养模型 四 梯队人才的管理 五 人才梯队建设发展通道 人才盘点 素质模型 人才盘点的内容 人才盘点的结果 人才分类 人才选拔 晋升与发展 今日
  • hive中常见的谓词操作符/比较符号

    hive中
  • STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • 一文带你了解芯片制造的6个关键步骤

    在智能手机等众多数码产品的更新迭代中 科技的改变悄然发生 苹果A15仿生芯片等尖端芯片正使得更多革新技术成为可能 这些芯片是如何被制造出来的 其中又有哪些关键步骤呢 智能手机 个人电脑 游戏机这类现代数码产品的强大性能已无需赘言 而这些强大
  • el-radio值无法回显

    首先检查 label 绑定一个动态变量 其次label为number类型可以直接回显 为string类型需要在最外层再加一层单引号
  • 【Android Socket专题】:UDP通信客户端app的demo的实现

    Android Socket 专题 UDP Client客户端 http blog csdn net shankezh article details 50731287 UDP Server服务器 http blog csdn net sh