Android之Socket的基於UDP傳輸


接收方創建步驟:

1.  創建一個DatagramSocket對象,並指定監聽的端口號

DatagramSocket socket = new  DatagramSocket (4567);

2. 創建一個byte數組用於接收

byte data[] = new byte[1024];

3. 創建一個空的DatagramPackage對象

 DatagramPackage package = new DatagramPackage(data , data.length);

4. 使用receive方法接收發送方所發送的數據,同時這也是一個阻塞的方法

socket.receive(package); 

5. 得到發送過來的數據

new String(package.getData() , package.getOffset() , package.getLength());

 

發送方創建步驟:

1.  創建一個DatagramSocket對象

DatagramSocket socket = new  DatagramSocket (4567);

2.  創建一個 InetAddress , 相當於是地址

InetAddress serverAddress = InetAddress.getByName("想要發送到的那個IP地址"); 

3.  這是隨意發送一個數據

String str = "hello";

4.  轉為byte類型

byte data[] = str.getBytes();

  5.  創建一個DatagramPacket 對象,並指定要講這個數據包發送到網絡當中的哪個地址,以及端口號

DatagramPacket  package = new DatagramPacket (data , data.length , serverAddress , 4567);

6.  調用DatagramSocket對象的send方法 發送數據

 socket . send(package);

 http://www.cnblogs.com/lee0oo0/archive/2012/04/04/2431907.html
 

一、有的手機不能直接接收UDP包,可能是手機廠商在定制Rom的時候把這個功能給關掉了。

1、可先在oncreate()方法里面實例化一個WifiManager.MulticastLock 對象lock;具體如下:

WifiManager manager = (WifiManager) this
                .getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock lock= manager.createMulticastLock("test wifi");

2、在調用廣播發送、接收報文之前先調用lock.acquire()方法;

3、用完之后及時調用lock.release()釋放資源,否決多次調用lock.acquire()方法,程序可能會崩,詳情請見

Caused by: java.lang.UnsupportedOperationException: Exceeded maximum number of wifi locks

注;記得在配置文件里面添加如下權限:

<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

經過這樣處理后,多數手機都能正常發送接收到廣播報文。

本小點轉載自Android手機接收不到UDP報文

二、在UDP通信中,android端發送UDP廣播包沒有問題。至於接收的話,有時候不能接收到包。

在UDP通信中,Android端發送UDP廣播包沒有問題。至於接收的話,有時候不能接收到包。但是如果UDP包中指定了目標主機的地址的話,那么android端就能正常接收。

下面上一段代碼,大家可用這段代碼進行測試

1、在一個Service里面,我們創建一個線程

public void onCreate() {//用於創建線程
        WifiManager manager = (WifiManager) this
                .getSystemService(Context.WIFI_SERVICE);
        udphelper = new UdpHelper(manager);
        
        //傳遞WifiManager對象,以便在UDPHelper類里面使用MulticastLock
        udphelper.addObserver(MsgReceiveService.this);
        tReceived = new Thread(udphelper);
        tReceived.start();
        super.onCreate();
    }

2、弄一個UDP幫助類,這個類主要用於發送和接收數據

package com.example.com.ihome.bang.util;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Observable;
import com.example.com.ihome.bang.tool.SendThread;
import android.net.wifi.WifiManager;
import android.util.Log;

/**
 * 
 * UdpHelper幫助類
 * 
 * @author 陳喆榕
 * 
 */
public class UdpHelper  implements Runnable {
    public    Boolean IsThreadDisable = false;//指示監聽線程是否終止
    private static WifiManager.MulticastLock lock;
    InetAddress mInetAddress;
    public UdpHelper(WifiManager manager) {
         this.lock= manager.createMulticastLock("UDPwifi"); 
    }
    public void StartListen()  {
        // UDP服務器監聽的端口
        Integer port = 8903;
        // 接收的字節大小,客戶端發送的數據不能超過這個大小
        byte[] message = new byte[100];
        try {
            // 建立Socket連接
            DatagramSocket datagramSocket = new DatagramSocket(port);
            datagramSocket.setBroadcast(true);
            DatagramPacket datagramPacket = new DatagramPacket(message,
                    message.length);
            try {
                while (!IsThreadDisable) {
                    // 准備接收數據
                    Log.d("UDP Demo", "准備接受");
                     this.lock.acquire();
                     
                    datagramSocket.receive(datagramPacket);
                    String strMsg=new String(datagramPacket.getData()).trim();
                    Log.d("UDP Demo", datagramPacket.getAddress()
                            .getHostAddress().toString()
                            + ":" +strMsg );this.lock.release();
                }
            } catch (IOException e) {//IOException
                e.printStackTrace();
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }

    }
    public static void send(String message) {
        message = (message == null ? "Hello IdeasAndroid!" : message);
        int server_port = 8904;
        Log.d("UDP Demo", "UDP發送數據:"+message);
        DatagramSocket s = null;
        try {
            s = new DatagramSocket();
        } catch (SocketException e) {
            e.printStackTrace();
        }
        InetAddress local = null;
        try {
            local = InetAddress.getByName("255.255.255.255");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        int msg_length = message.length();
        byte[] messageByte = message.getBytes();
        DatagramPacket p = new DatagramPacket(messageByte, msg_length, local,
                server_port);
        try {

            s.send(p);
            s.close();
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
            StartListen();
    }
}

最后, 添加個人的實例 :

package com.example.android.helloactivity;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.example.andriod.udp.UDPClient;
import com.example.andriod.udp.UDPServer;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainAct extends Activity {
    EditText msg_et = null;
    Button send_bt = null;
    TextView info_tv = null;
    private static final String TAG ="MainAct";
    private UDPClient client;
    private String sendInfo;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.udp_test);
        msg_et = (EditText) findViewById(R.id.edit_msg);
        send_bt = (Button) findViewById(R.id.send_bt);
        info_tv = (TextView) findViewById(R.id.receive_msg);
        info_tv.setText("source");
        // 開啟服務器
        ExecutorService exec = Executors.newCachedThreadPool();
        UDPServer server = new UDPServer();
        exec.execute(server);
        // 發送消息
        send_bt.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                myThread1 thread = new myThread1("22");
                new Thread(thread).start();

            }
        });
    }

    final Handler mHander = new Handler() {

        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            //super.handleMessage(msg);
            info_tv.setText(sendInfo);
            
            Log.d(TAG, "client.send()=");
        }
    };

    class myThread1 implements Runnable {

        private String threadName;

        public myThread1(String name) {
            this.threadName = name;
        }

        public void run() {
            Log.d(TAG, "MyThread  execu"+msg_et.getText().toString());
            client = new UDPClient(msg_et.getText().toString());
            sendInfo=client.send();
            
            Message msg = mHander.obtainMessage();
            msg.arg1=1;
            mHander.sendMessage(msg);
            Log.d(TAG, "client.send()=");
        }
    }
}
package com.example.andriod.udp;

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

import android.util.Log;

public class UDPServer implements Runnable {
    private static final int PORT = 6000;
    private byte[] msg = new byte[2048];
    private boolean life = true;

    public UDPServer() {
    }

    public boolean isLife() {
        return life;
    }

    public void setLife(boolean life) {
        this.life = life;
    }

    @Override
    public void run() {
        DatagramSocket dSocket = null;
        DatagramPacket dPacket = new DatagramPacket(msg, msg.length);
        try {
            dSocket = new DatagramSocket(PORT);
            while (life) {
                try {
                    dSocket.receive(dPacket);
                    Log.d("tian msg sever received",
                            new String(dPacket.getData(), dPacket.getOffset(),
                                    dPacket.getLength())
                                    + "dPacket.getLength()="
                                    + dPacket.getLength());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
}
package com.example.andriod.udp;

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

import android.util.Log;

public class UDPClient {
    private static final int SERVER_PORT = 6000;
    private DatagramSocket dSocket = null;
    private String msg;

    public UDPClient(String msg) {
        super();
        this.msg = msg;
    }

    public String send() {
        StringBuilder sb = new StringBuilder();
        InetAddress local = null;
        try {
            local = InetAddress.getByName("localhost"); // 本機測試
            sb.append("已找到服務器,連接中...").append("/n");
        } catch (UnknownHostException e) {
            sb.append("未找到服務器.").append("/n");
            e.printStackTrace();
        }
        try {
            dSocket = new DatagramSocket(); // 注意此處要先在配置文件里設置權限,否則會拋權限不足的異常
            sb.append("正在連接服務器...").append("/n");
        } catch (SocketException e) {
            e.printStackTrace();
            sb.append("服務器連接失敗.").append("/n");
        }
        int msg_len = msg == null ? 0 : msg.length();
        DatagramPacket dPacket = new DatagramPacket(msg.getBytes(), msg_len,
                local, SERVER_PORT);
        try {
            dSocket.send(dPacket);
            Log.d("tian", "msg=="+msg+"dpackage="+dPacket.getData()+"dPacket.leng="+dPacket.getLength());
            sb.append("消息發送成功!").append("/n");
        } catch (IOException e) {
            e.printStackTrace();
            sb.append("消息發送失敗.").append("/n");
        }
        dSocket.close();
        return sb.toString();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM