欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android:Socket UDP通信

程序员文章站 2024-02-11 08:01:58
...

UDP 是User Datagram Protocol的简称,一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

1、UDP是一个无连接协议,传输数据之前源端和终端不建立连接;

2、不维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息;

3、UDP信息包的标题很短,8个字节,对于TCP的20个字节信息包的额外开销很小;

4、吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制;

5、不保证可靠交付;

6、UDP是面向报文的。

二、UDP的代码编程需要用到DatagramSocket类.java使DatagramSocket代表UDP协议的Socket,先了解一下这个类。
sever服务端创建步骤:
1、生成DatagramSocket对象,参数为端口号

DatagramSocket socket = new  DatagramSocket (8888);

2、byte数组用来接收数据

byte data[] = new byte[1024];

3、DatagramPackage以包形式装载byte数组

DatagramPacket packet = new DatagramPacket(data, data.length);

4、使用DatagramPacket的receive方法接收发送方所发送的数据,是一个阻塞的方法

socket.receive(packet);

5、接收到的数据转变化成可读字符串

String result = new String(packet.getData(), packet.getOffset(), packet.getLength());

client客户端创建步骤:

1、生成DatagramSoctet对象,参数为端口号

DatagramSocket socket = new  DatagramSocket (8888);

2、创建一个InetAddress对象,用于确定server客户端,参数为IP地址。

InetAddress serverAddress = InetAddress.getByName("192.168.1.103");

3、需要发送的数据转化为byte数组

String sendData= "hello word";
byte data[] = sendData.getBytes();

4、生成一个DatagramPacket对象,包含需要发送的数组,byte数组,已设置IP地址的serverAddress,和服务端一致的端口号(这里是8888)

DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, 8888);

5、发送数据,调用DatagramSocket对象的send方法

socket.send(packet);

demo演示:
这里特别强调一点的就是,网络等延时通信不能放到主线上进行通信:



/**
 * Created by  on 2017/5/26.
 */

public class UdpClient {
    private static DatagramSocket sendUdp=null;
    private static DatagramSocket recvUdp=null;
    private static DatagramPacket sendPkt=null;
    private static DatagramPacket recvPkt=null;
    private static ReceiveThread rThread=null;
    public static String remoteIP="192.168.1.216";
    public static int remotePort = 60000;
    public static int localPort = 60000;
    public static InetAddress remoteAddr;

    private static byte[] recvBuff = new byte[1024];
    private static byte[] sendBuff = null;
    public static void initUdp()
    {
        try
        {
            sendUdp = new DatagramSocket(0);
            remoteAddr = InetAddress.getByName(remoteIP);

            //接收消息
            recvUdp = new DatagramSocket(localPort);
            recvPkt = new DatagramPacket(recvBuff, recvBuff.length);
            rThread = new ReceiveThread();
            rThread.start();

        } catch (SocketException e)
        {
            e.printStackTrace();
        } catch (UnknownHostException e)
        {
            e.printStackTrace();
        }
    }

    public static void SendMessage(String jsonObject)
    {
        try
        {
            sendBuff = jsonObject.getBytes("UTF-8");
            sendPkt = new DatagramPacket(sendBuff, sendBuff.length, remoteAddr, remotePort);
            try
            {
                //sendUdp.send(sendPkt);
                recvUdp.send(sendPkt);
            } catch (IOException e)
            {
                e.printStackTrace();
            }

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

    }

    /**
     * 接收数据
     */
    private static class ReceiveThread extends Thread
    {
        @Override
        public void run()
        {
            super.run();
            while (true)
            {
                if (recvUdp != null)
                {
                    try
                    {
                        recvUdp.receive(recvPkt);  //接收数据
                        Message msg = new Message();
                        msg.what = 0x01;
                        msg.obj = new String(recvPkt.getData());
                        //System.out.println(msg.obj.toString());
                        MainActivity.handler.sendMessage(msg);

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



}

在Activity中开启线程进行通信:

   final UdpClient udp=new UdpClient();
        //发送所需要的信息
       new Thread(){
           @Override
           public void run() {
               super.run();
               udp.initUdp();
               udp.SendMessage("1");
           }
       }.start();
        //接受服务器返回的状态
        handler=new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what==0x01){
                    btn_main_mode.setText("手动");
                    btn_main_mode.setBackgroundColor(Color.BLUE);
                }
            }
        };

在这段程序中,用handle 进行主线程和通信线程的通信,数据传递。同时最后不要忘记,要对所受用的权限进行注册。