Android 发送udp消息

参考,感谢两位大哥的文章

http://www.cnblogs.com/liqw/p/4867657.html
https://blog.csdn.net/u012106397/article/details/51492867

udp很早就听说过,但是由于其是面向无连接的协议,因此一直很少用到。但是在一些即时通讯方面,由于对延时有较高的要求,因此还是会使用到。

 

1.Android 发送udp消息

首先呢,java使用DatagramSocket来发送消息,消息的内容就放在DatagramPacket中。

package com.example.udpsender;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

//来源:http://www.cnblogs.com/liqw/p/4867657.html
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "MainActivity";

    private Button mBtnSendUdpMessage;
    private DatagramSocket socket = null;
    private InetAddress serverAddress = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            //自己的发送端口
            socket = new DatagramSocket(12345);  //①
            //对方的ip
            serverAddress = InetAddress.getByName("192.168.1.54");  //②
        } catch (Exception e) {
            e.printStackTrace();
        }

        mBtnSendUdpMessage = findViewById(R.id.btn_send_udp_message);
        mBtnSendUdpMessage.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_send_udp_message:
                sendMessage();
                break;
        }
    }

    private void sendMessage() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String sendData = "hello world";
                    byte data[] = sendData.getBytes();
                    //这里的8888是接收方的端口号
                    Log.d(TAG, "run: 发送消息");
                    DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, 8888);   //③
                    socket.send(packet);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

(1)布局上就是一个按钮,用来发送消息,就不发了。

(2)在①处new了一个socket,这里的端口12345是直接发送udp消息的端口,同时也是自己监听udp消息的端口,下面的192.168.1.54 是对方的ip

(3)在子线程中new了一个DatagramPacket对象,里面包含了具体的数据和对方的端口8888.

2.服务器端接受udp消息

首先要新建一个java项目,(居然连web项目也不需要,重点还是刚刚提到的那两个包)

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

public class UDPServer {
    private String message = "";
    private String send = "";
    public static void main(String[] args) throws IOException {
        UDPServer udpServer = new UDPServer();
        udpServer.receiveUdpMessage();
    }

    private void receiveUdpMessage() {
        //http://www.cnblogs.com/liqw/p/4867657.html
        System.out.println("开始----------------------------");
        DatagramSocket socket = null;
        try {
            //若发送消息,则使用8888端口
            socket = new DatagramSocket(8888);
        } catch (Exception e) {
            e.printStackTrace();
        }
        while (true) {
            try {
                byte[] data = new byte[1024];
                DatagramPacket packet = new DatagramPacket(data, data.length);
                socket.receive(packet);
                System.out.println(packet.getAddress());   // /ip
                System.out.println(packet.getPort());  //端口
                System.out.println(packet.getSocketAddress());  //  /ip:端口
                message = new String(packet.getData(), packet.getOffset(), packet.getLength());
                send = message;
                System.out.println("receive client's data: " + message);
                if (!send.equals("")) {
                    sendUdpMessage();
                    send = "";
                }
//                System.out.println("receive client's data: " + message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void sendUdpMessage() {
        //https://blog.csdn.net/u012106397/article/details/51492867
        new Thread(() -> {
            try {
                DatagramSocket dgSocket = new DatagramSocket();
                System.out.println("发送消息:" + message);
                byte[] data = message.getBytes();
                DatagramPacket dgPacket = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.1.62"), 12345);
                dgSocket.send(dgPacket);
                dgSocket.close();
                System.out.println("send message is ok.");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
}

(1)和上面一样,监听自己的8888端口,

(2)用一个while的循环来获取需要打印的消息,这个receiveUdpMessage方法里面还顺便打印了ip和端口,可以看到客户端的ip和端口

(3)下面的sendUdpMessage方法可以将消息利用udp发送到客户端

3.Android 接受udp消息

package com.example.udpreceiver;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent(this, UdpReceiverService.class);
        Log.v("WANGRUI", "准备启动service...............");
        startService(intent);
        Log.v("WANGRUI", "开启service...............");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.v("WANGRUI", "stopservice 被调用。。。。。。。。。");
        Intent intent = new Intent(this, UdpReceiverService.class);
        stopService(intent);
    }
}

(1)接收端界面什么都没有,MainActivity就是开启了一个服务来接受消息

package com.example.udpreceiver;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

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

//https://blog.csdn.net/u012106397/article/details/51492867
public class UdpReceiverService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread() {
            public void run() {
                while (true) {
                    try {
                        DatagramSocket dgSocket = null;
                        int port = 12345;
                        dgSocket = new DatagramSocket(null);
                        dgSocket.setReuseAddress(true);
                        dgSocket.bind(new InetSocketAddress(port));
                        byte[] by = new byte[1024];
                        DatagramPacket packet = new DatagramPacket(by, by.length);
                        dgSocket.receive(packet);
                        String str = new String(packet.getData(), 0, packet.getLength());
                        System.out.println("接收到的数据为:" + str);
                        Log.v("WANGRUI", "已获取服务器端发过来的数据。。。。。" + str);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

最后再次感谢两位大哥的文章

http://www.cnblogs.com/liqw/p/4867657.html
https://blog.csdn.net/u012106397/article/details/51492867
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值