一起Talk Android吧(第三百三十回:Android中网络通信之UPD通信演示)

本文详细介绍了Android中使用UDP进行网络通信的实现,包括发送端和接收端的代码实现。通过创建UDPReceive1和UDPSend1类,分别实现了数据的接收和发送,并在主程序中通过多线程模拟了通信过程。关键点包括数据的封装、异常处理以及如何通过特定数据(如'quit')结束通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

各位看官们,大家好,上一回中咱们说的是Android中网络通信之UDP Socket的例子,这一回中咱们说的例子是UDP通信演示。闲话休提,言归正转。让我们一起Talk Android吧!

我们在前面章回中介绍了UDP通信的流程以及UDP Socket接口和数据包,本章回中将介绍如何在通信过程中使用这些接口。

接收端演示

我们定义了一个名叫UDPReceive1的类,类的成员主要是DatagramSocket类和DatagramPacket类的对象,它们代表UDP的Socket和数据包。

接下来我们介绍类中的成员方法:

receiveData()

该方法封装了DatagramSocket类中的receive()方法,它主要用来接收发送方发来的数据,接收的数据存放在数据包中,数据包中存放数据的缓冲区大小为1024字节。接收到数据后,我们把byte类型的数据转换成了string类型,这样方便我们查看。

closeReceiveSocket()

该方法封装了DatagramSocket类中的close()方法,主要用来关闭Socket.

下面是程序的完整代码,请大家参考:

package com.extato;

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

public class UDPReceive1 {
    private DatagramSocket mDatagramSocket;
    private DatagramPacket mDatagramPacket;
    private byte [] dataByte;
    int dataLength;

    public UDPReceive1(DatagramSocket socket) {
        mDatagramSocket = socket;
        dataLength = 1024;
        dataByte = new byte[dataLength];
        mDatagramPacket = new DatagramPacket(dataByte,dataLength);
    }

    public String receiveData() {
        String receData = null;
        int length;
        byte [] bytes;

        if(mDatagramSocket != null) {
            try {
                mDatagramSocket.receive(mDatagramPacket);
            }catch (IOException e) {
                System.out.println("Receive data exception: "+e.toString());
            }

            if(mDatagramPacket != null) {

                length = mDatagramPacket.getLength();
                bytes = mDatagramPacket.getData();
                StringBuilder stringBuilder = new StringBuilder();
                for(int i=0; i<length; i++) {
                    stringBuilder.append( String.format("%c",bytes[i]) );
                }

//                stringBuilder.append(" IP: ").append(mDatagramPacket.getAddress().getHostAddress());
                stringBuilder.append(" Port: ").append(mDatagramPacket.getPort());
                receData = stringBuilder.toString();
                System.out.println(">>> UDP Receive: "+receData);
            }
        }

        return  receData;
    }

    public void closeReceiveSocket () {
        if(mDatagramSocket != null) {// && !mDatagramSocket.isClosed()) {
            System.out.println(">>> Receive Close Socket");
            mDatagramSocket.close();
        }
    }

}

发送端演示

我们定义了一个名叫UDPSend1的类,类的成员主要是DatagramSocket类和DatagramPacket类的对象,它们代表UDP的Socket和数据包。类中还有一个int类型的成员变量,它表示UDP通信中的端口号。

接下来我们介绍类中的成员方法:

sendData(String data)

该方法封装了DatagramSocket类中的send()方法,它主要用来发送数据。被发送的数据存放在它的参数中,不过该数据的类型是string,我们不能直接发送,需要把它封装到数据包中后才能发送。

closeSendSocket()

该方法封装了DatagramSocket类中的close()方法,主要用来关闭Socket.

下面是程序的完整代码,请大家参考:

package com.extato;

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

public class UDPSend1 {
    private DatagramSocket mUDPSocket;
    private DatagramPacket mDatagramPacket;
    private String mUDPData;
    private int postPort; //this port is used for sending data

    public UDPSend1(DatagramSocket socket, int port) {
        postPort = port;
        mUDPSocket = socket;
    }


    public void sendData(String data) {
        if(mUDPSocket != null) {
            try {
                System.out.println("<<< UDP Send: "+data);
                //IP地址使用当前电脑的IP地址
                InetAddress address =  InetAddress.getLocalHost();
                mDatagramPacket = new DatagramPacket(data.getBytes(),data.getBytes().length,address,postPort);
                mUDPSocket.send(mDatagramPacket);
            }catch (IOException e) {
                System.out.println("Socket send Data Exception: "+e.toString());
            }
        }else {
            System.out.println("Socket is null");
        }
    }


    public void closeSendSocket() {
        if(mUDPSocket != null && mUDPSocket.isClosed()) {
            System.out.println("<<< Send close socket");
            mUDPSocket.close();
        }
    }


}

UDP通信演示

我们创建了主程序main,在主程序中分别创建了UDPReceive1类和UDPSend1类的对象,分别表示UDP通信的接收方和发送方。为了分开处理发送方和接收方的程序逻辑,我们创建了两个子线程。

发送方所在的子线程中不停地发送数据,直到最后一条数据为止。接收方所在的子线程不停地接收数据,直到收到最后一条数据为止,然后关闭Socket.

主程序中我们使用ArrayList对象来存放数据,大家在实际项目中可以依据项目需要来自定义数据的存储方式。此外,为了方便演示,主程序中的发送方和接收方共用一个Socket对象,其实使用两个socket对象也是可以的,就是说发送方和接收方各自使用一个Socket对象。不管使用几个Socket对象,只要保证接收方Socket对象中的端口和发送方数据包中的端口一致就可以。大家可以自已动手实践一下。下面是程序的完整代码,请大家参考:

package com.extato;

import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
	// write your code hereo
        int port = 3200;
        DatagramSocket datagramSocket = null;
        UDPReceive1 udpReceive1 =  null;
        UDPSend1 udpSend1 = null;

        //Create UDP socket
        try {
            datagramSocket =  new DatagramSocket(port);
        }catch (SocketException e) {
           System.out.println("new Socket Exception: "+e.toString()); 
        }


        if(datagramSocket != null) {
            udpReceive1 = new UDPReceive1(datagramSocket);
            udpSend1 = new UDPSend1(datagramSocket,port);
        }else {
            System.out.println("Socket is null and init send and receive failed.");
        }

        UDPReceive1 finalUdpReceive = udpReceive1;
        Thread receiveThread = new Thread(new Runnable() {
            String data = null;
            boolean flag = true;
            @Override
            public void run() {
                while (flag) {
                    data = finalUdpReceive.receiveData();

                    if(data.contains("quit")) {
                        flag = false;
                    }
                }

                finalUdpReceive.closeReceiveSocket();
            }
        });


        ArrayList<String> dataArray = new ArrayList<>();
        for(int i=1; i<6; ++i) {
            dataArray.add("This is data: "+i);
        }
        dataArray.add("quit");

        UDPSend1 finalUdpSend = udpSend1;
        Thread sendThread = new Thread(new Runnable() {
            String data = null;

            @Override
            public void run() {
                data = "send data from sendThread";
                for(String item: dataArray) {
                    finalUdpSend.sendData(item);
                }
            }
        });

        receiveThread.start();
        sendThread.start();
    }

}

下面说一下程序的注意事项:

  1. 我们使用IntelliJ IDEA创建了工程来编译和运行程序,而不是像以往一样使用jdk命令直接编译程序,这样做是为了调试程序方便一些。
  2. 发送和接收数据时都会有IO异常发生,需要处理异常。
  3. 程序中没有指定IP地址,而是默认使用当前电脑的IP地址;
  4. 我们使用最后一条数据为"quit"这个特征巧妙地结束了UDP通信过程,大家在实际项目中可以通过其它方式结束通信,不然会导致线程不停地运行,而且UDP通信也没有结束。

编译并且运行上面的程序,可以得到以下结果:

<<< UDP Send: This is data: 1
<<< UDP Send: This is data: 2
<<< UDP Send: This is data: 3
<<< UDP Send: This is data: 4
<<< UDP Send: This is data: 5
<<< UDP Send: quit
>>> UDP Receive: This is data: 1 Port: 3200
>>> UDP Receive: This is data: 2 Port: 3200
>>> UDP Receive: This is data: 3 Port: 3200
>>> UDP Receive: This is data: 4 Port: 3200
>>> UDP Receive: This is data: 5 Port: 3200
>>> UDP Receive: quit Port: 3200
>>> Receive Close Socket

Process finished with exit code 0

看官们,关于Android中网络通信之UDP通信演示的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

talk_8

真诚赞赏,手有余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值