Android UDP连接发送请求和接受请求的例子

UDP请求的发送


<span style="font-size:14px;">import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;

import com.changhong.electric_controll.UDPResponseCallback;
import com.changhong.electric_controll.util.ByteUtils;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

public class UDPBroadCast extends Thread {
    private MulticastSocket sender = null;
    private DatagramSocket datagramSocket=null;
    private DatagramPacket dj = null;
    private InetAddress group = null;
    private UDPReceiveAndTCPSend mUDPReceiveAndTCPSnd;

    private UDPResponseCallback callback;   //自定义接口,用于处理接收到的UDP结果,主要是调用它唯一的方法onResponse,提高结果处理的灵活性

    public String LocalIP;

    public int DEFAULT_PORT=12426;

    private byte[] data = new byte[1024];   //用于发送udp的byte数组

    private boolean isudpsendfinished=false;

    private Context mContext;

    public UDPBroadCast(Context context,byte[] dataString, UDPResponseCallback callback) {
        mContext=context;
        this.data = dataString;
        this.callback=callback;
        }


    @Override
    public void run() {
            try {
                if(datagramSocket==null){
                    datagramSocket = new DatagramSocket(null);
                    datagramSocket.setReuseAddress(true);
                    datagramSocket.bind(new InetSocketAddress(DEFAULT_PORT));
                }
                sender = new MulticastSocket();
                LocalIP=getWIFIIP(mContext);
                LocalIP=getBoradcastIP(LocalIP);
                Log.i("Data","LocalIp="+LocalIP);
                group = InetAddress.getByName(LocalIP);    //这个是我客户端的IP地址,也可以是客户端所在的网段的广播地址,也可以是虚拟广播地址
                if(data.length != 0) {
                    dj = new DatagramPacket(data, data.length, group,DEFAULT_PORT);    //端口号可以自己随便定,发送至的端口号

                    datagramSocket.send(dj);    //发送UDP广播
                    Log.i("Data", "发送的内容是" + ByteUtils.bytesToHexString(data));
                    datagramSocket.close();
                    isudpsendfinished=true;
                    ReUDPAndSenTCP();     //用于接收UDP响应的线程
                }

            } catch(IOException e) {
                Log.i("Data","UDPBroadCast已经挂啦");
                e.printStackTrace();
            }
        }

    public void onStop() {
        Log.i("Data","datagramSocket是否连接="+datagramSocket.isConnected()+",是否关闭="+datagramSocket.isClosed());
        if (!datagramSocket.isConnected() || datagramSocket.isClosed()) {
            Log.i("Data", "datagramSocket已关闭");
            datagramSocket.close();
        }
        this.interrupt();
        Log.i("Data", "线程停止");
    }


    public void ReUDPAndSenTCP(){
        if(isudpsendfinished){
            if( mUDPReceiveAndTCPSnd == null) {
                mUDPReceiveAndTCPSnd = new UDPReceiveAndTCPSend(callback);
                mUDPReceiveAndTCPSnd.start();
            }
        }
    }

    public String getLocalIpAddress()
    {
        try
        {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
            {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
                {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress())
                    {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        }
        catch (SocketException ex)
        {
            Log.e("Data","WifiPreference IpAddress"+ ex.toString());
        }
        return null;
    }

    public String getBoradcastIP(String IP){

        String temp=IP.substring(0,11);   //因为这是一个b类地址
        Log.i("Data","temp="+temp);
        StringBuffer buffer=new StringBuffer();
        buffer.append(temp);
        buffer.append("255");
        return buffer.toString();

    }

    public String getWIFIIP(Context context){
        WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int ipAddress = wifiInfo.getIpAddress();
        String SSID=wifiInfo.getSSID();
        Log.i("Data","SSID="+SSID);
        String IPAddress=intToIp(ipAddress);     //获取WIFI的IP地址
        return IPAddress;
    }

    public String intToIp(int i) {
        return (( i & 0xFF)+ "."+ ((i >> 8 ) & 0xFF) + "."
                + ((i >> 16 ) & 0xFF)  + "." +((i >> 24 ) & 0xFF ));  }
}
</span>


UDP接收服务器响应内容

<span style="font-size:14px;">import android.util.Log;

import com.changhong.electric_controll.UDPResponseCallback;
import com.changhong.electric_controll.connect.entity.entity.UDPAccept;
import com.changhong.electric_controll.connect.entity.parser.UDPDataParser;
import com.changhong.electric_controll.util.ByteUtils;

import org.apache.http.conn.util.InetAddressUtils;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;


/*接收udp多播 并 发送tcp 连接*/
public class UDPReceiveAndTCPSend extends  Thread {
    UDPResponseCallback mUDPResponseCallback;

    public DatagramSocket datagramSocket=null;

    public DatagramPacket dp;

    public UDPDataParser mUDPParser;

    public UDPAccept mUDPAccept;

    public String mIPaddress;

    public String mPort;

    public int DEFAULT_PORT=12426;

    public StringBuffer sb;

    public UDPReceiveAndTCPSend(UDPResponseCallback callback){
        this.mUDPResponseCallback=callback;
        mUDPParser=new UDPDataParser();

    }
    @Override
    public void run() {
        byte[] data = new byte[1024];
        try {
            if(datagramSocket==null) {
                datagramSocket=new DatagramSocket(null);
                datagramSocket.setReuseAddress(true);
                datagramSocket.bind(new InetSocketAddress(DEFAULT_PORT));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        while (true) {
            try {
                dp = new DatagramPacket(data, data.length);
                if (datagramSocket != null) {
                    datagramSocket.receive(dp);
                }
            } catch (Exception e) {
                Log.i("Data","UDPReceeive 已经挂啦");
                e.printStackTrace();
            }
            if(dp != null){
                String response= ByteUtils.bytesToHexString(dp.getData());
                Log.i("Data", "UDP response = " + response);
                byte[] data1=dp.getData();
                mUDPAccept=mUDPParser.analysis(data1);
                if(mUDPAccept != null) {
                    mIPaddress = mUDPParser.setIPAddress(mUDPAccept.getIPAddress());
                    mPort =mUDPParser.setPort(mUDPAccept.getPort());
                }
                Log.i("Data", "The Ip=" + mIPaddress);
                Log.i("Data","The Port = "+mPort);
                if (mIPaddress != null) {
                    final String quest_ip = dp.getAddress().toString().substring(1);   //从UDP包中解析出IP地址
                    String host_ip = getLocalHostIp();   //若udp包的ip地址 是 本机的ip地址的话,丢掉这个包(不处理)
                    if ((!host_ip.equals("")) && host_ip.equals(quest_ip.substring(1))) {
                        continue;
                    }
                    if(mIPaddress.equals("0.0.0.0")){
                        mUDPResponseCallback.onResponse(null,false);
                    }
                    sb=new StringBuffer();
                    sb.append(mIPaddress);
                    sb.append(",");
                    sb.append(mPort);
                    Log.i("Data","UDP result="+sb.toString());
                    mUDPResponseCallback.onResponse(sb.toString(), true);     //将IP地址传递回去
                    datagramSocket.close();
                    break;
                }

            }

        }
    }



    public String getLocalHostIp() {
        String ipaddress = "";
        try {
            Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
            // 遍历所用的网络接口
            while (en.hasMoreElements()) {
                NetworkInterface nif = en.nextElement();// 得到每一个网络接口绑定的所有ip
                Enumeration<InetAddress> inet = nif.getInetAddresses();
                // 遍历每一个接口绑定的所有ip
                while (inet.hasMoreElements()) {
                    InetAddress ip = inet.nextElement();
                    if (!ip.isLoopbackAddress()
                            && InetAddressUtils.isIPv4Address(ip
                            .getHostAddress())) {
                        return ip.getHostAddress();
                    }
                }
            }
        }
        catch(SocketException e)
        {
            Log.e("Data", "获取本地ip地址失败");
            e.printStackTrace();
        }
        return ipaddress;
    }


}
</span>

用到的自定义接口 UDPResponseCallback.java

 
 
<span style="font-size:14px;">public interface UDPResponseCallback {

        public void onResponse(String response,boolean isSuccess);

}</span><strong style="font-size: 12pt;">
</strong>

在Activity中通过点击按钮发送和接收响应并处理响应内容

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;

import android.os.Bundle;

import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.support.v7.app.ActionBarActivity;

import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;


import com.changhong.electric_controll.connect.entity.parser.UDPDataParser;
import com.changhong.electric_controll.util.ByteUtils;
import com.changhong.electric_controll.thread.UDPBroadCast;
import com.changhong.electric_controll.util.WifiUtil;


public class MainActivity extends ActionBarActivity implements View.OnClickListener{

    private String TAG="MainActivity";

    private TextView result_text;

    private Button submit;

    private Button cancel;

    private AlertDialog wifiConfigDialig;

    private ProgressDialog mProgressDialog;

    public UDPBroadCast mUDPBroadCast;    //UDP连接线程

    public boolean ifTCPSendFinished=false;   //用来判断TCP连接是否完成

    public byte[] sendData;     //存放发送的UDP数据

    private final static int DisProcess = 0x123;

    private SocketTimeCounter timeCounter;    //计时器

    private static final int TIME_MILLIS=60*1000;

    public Handler mhandler=new Handler(){
        public void handleMessage(Message msg){
            switch(msg.what){
                case DisProcess:
                    disAsynProgressDialog();
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initview();
    }

    /**
     * 初始化控件
     **/
    private void initview() {

        //result_text = (TextView) findViewById(R.id.result);

        submit = (Button) findViewById(R.id.start_config);

        cancel = (Button) findViewById(R.id.cancel_config);

        submit.setOnClickListener(this);

        cancel.setOnClickListener(this);
    }


    /**发送UDP广播并接收UDP广播,从中解析出IP地址
     *
     * OnResponse用于处理接收到的UDP包的内容
     *
     * **/

    public void SenUDPBroadCast(byte[] sendBytes){
        if(mUDPBroadCast != null){
            mUDPBroadCast.onStop();
            mUDPBroadCast=null;
        }
        mUDPBroadCast = new UDPBroadCast(MainActivity.this,sendBytes, new UDPResponseCallback() {
            @Override
            public void onResponse(String response,boolean isSuccess) {
                try {
                    if(TextUtils.isEmpty(response)){
                        return;
                    }
                    if(!isSuccess){
                        Log.i("Data","MainActivity 连接失败,请重新连接");
                        disAsynProgressDialog();
                        showToast("连接失败,请重新连接");
                        stopTimeCounter();
                        return ;
                    }
                    Log.i("Data","设置显示信息");
                    String IPAddress=response.split(",")[0];
                    String Port=response.split(",")[1];
                    Log.i("Data", "MainActivity IP=" + IPAddress);
                    Log.i("Data", "MainActivity Port=" + Port);
                    ifTCPSendFinished=true;
                    disAsynProgressDialog();

                    Intent intent=new Intent(MainActivity.this, ShowInfoActivity.class);
                    intent.putExtra(ShowInfoActivity.IPADDRESS,IPAddress);
                    intent.putExtra(ShowInfoActivity.PORT,Port);
                    startActivity(intent);
                    MainActivity.this.finish();

                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        });
        mUDPBroadCast.start();
    }


    /**
     * 点击配置按钮之后的后续操作
     **/
    public void submit() {
            //这里写对数组byte的初始化
            sendData=new UDPDataParser().build();
            Log.i("Data", "发送的数据是" + ByteUtils.bytesToHexString(sendData));
            startTimeCounter(TIME_MILLIS,TIME_MILLIS/2);     //开启计时器
            SenUDPBroadCast(sendData);    //开始UDP连接
            showAsyncProgressDialog("正在连接设备...",true);
    }

    /**
     * toast提示
     **/
    public void showToast(String toastmessage) {
        Toast.makeText(this, toastmessage, Toast.LENGTH_SHORT).show();
    }

    /**
     * 数据加载小菊花
     *
     * @param msg      内容
     * @param isCancel 是否允许关闭 true - 允许  false - 不允许
     */
    public void showAsyncProgressDialog(final String msg, final boolean isCancel) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    if (mProgressDialog == null) {
                        mProgressDialog = new ProgressDialog(MainActivity.this);
                    }
                    if (mProgressDialog.isShowing()) {
                        return;
                    }
                    mProgressDialog.setMessage(msg);
                    mProgressDialog.setCancelable(isCancel);
                    mProgressDialog.setCanceledOnTouchOutside(false);
                    mProgressDialog.setOnCancelListener(null);
                    mProgressDialog.show();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 隐藏数据加载的进度小菊花
     **/
    public void disAsynProgressDialog() {

        try {
            if (mProgressDialog != null || mProgressDialog.isShowing()) {
                runOnUiThread(
                        new Runnable() {
                            @Override
                            public void run() {
                                mProgressDialog.dismiss();
                            }
                        }
                );
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void onDestroy(){
        super.onDestroy();
        Log.i("Data","MainActivity 执行OnDestroy方法");
        mUDPBroadCast.onStop();
        stopTimeCounter();
    }

    /**关闭计时器**/
    public void stopTimeCounter(){
        if (null != timeCounter) {
            Log.i("Data", "stop Timeout Counter");
            timeCounter.cancel();
            timeCounter = null;
        }
    }
    /**开启计数器**/
    public void startTimeCounter(int Millis,int interval){
        stopTimeCounter();   //如果计时器已经开启,先关闭原来的,再重新开启
        Log.i("Data","启动计时器");
        timeCounter=new SocketTimeCounter(Millis,interval);
        timeCounter.start();
    }
    @Override
    public void onClick(View v) {

        switch(v.getId()){
            case R.id.start_config:
                submit();
                break;
            case R.id.cancel_config:
                break;
        }
    }

      /**计时器**/
    private class SocketTimeCounter extends CountDownTimer {

        public SocketTimeCounter(int millistime,int interval){
            super(millistime,interval);
        }

        @Override
        public void onTick(long millisUntilFinished) {

        }

        @Override
        public void onFinish() {
            if(!ifTCPSendFinished){
                if(!MainActivity.this.isFinishing()) {
                    disAsynProgressDialog();
                    mUDPBroadCast.onStop();
                    showToast("连接超时");
                }
            }
        }
    }


}





猜你喜欢

转载自blog.csdn.net/qq_31490071/article/details/51670059
今日推荐