• Android UDP


    一、UDP协议全称是用户数据报协议 ,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。

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

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

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

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

    5、不保证可靠交付;

    6、UDP是面向报文的。

    二、UDP的代码编程需要用到DatagramSocket类,Java使用DatagramSocket代表UDP协议的Socket,先了解一下如何使用这个类。

    server服务端(接收数据方)创建步骤

     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、生成DatagramSocket对象,参数为端口号

    DatagramSocket socket = new  DatagramSocket (8888);
    

    2、创建一个InetAddress对象,用于确定server客户端(数据接收方),参数为IP地址,如我的IP地址为192.168.1.103

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

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

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

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

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

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

    socket.send(packet);
    

    三、代码demo演示

    server服务端,可以直接运行在eclipse即可

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    public class UDPServer {
    	public static void main(String[] args) throws IOException {
    		DatagramSocket socket = null;
    		try {
    			socket = new DatagramSocket(8888);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		while (true) {
    			byte data[] = new byte[1024];
    			DatagramPacket packet = new DatagramPacket(data, data.length);
    			socket.receive(packet);
    			String result = new String(packet.getData(), packet.getOffset(), packet.getLength());
    			System.out.println("receive client's data: " + result);
    		}
    	}
    }
    

    若多次运行会提示错误:Address already in use: Cannot bind,关掉之前开启的即可。

    Android客户端代码demo演示,需要注意的是端口号是与服务端一致的,IP地址是服务端的IP地址。

    import android.app.Activity;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    
    public class UDPActivity extends Activity {
    	private Button bt_send_data = null;
    	DatagramSocket socket = null;
    	InetAddress serverAddress = null;
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		bt_send_data = new Button(this);
    		bt_send_data.setText("发送");
    		setContentView(bt_send_data);
    		try {
    			socket = new DatagramSocket(8888);
    			serverAddress = InetAddress.getByName("192.168.1.101");
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		bt_send_data.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				new Thread(new Runnable() {
    					@Override
    					public void run() {
    						try {
    							String sendData = "hello world";
    							byte data[] = sendData.getBytes();
    							DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, 8888);
    							socket.send(packet);
    						} catch (Exception e) {
    							e.printStackTrace();
    						}
    					}
    				}).start();
    			}
    		});
    	}
    }
    

    在AndroidManifest.xml添加权限和注册

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.libill.demos"
        android:versionCode="1"
        android:versionName="1.0" >
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="10" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    	<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
     	<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
     	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
     	<uses-permission android:name="android.permission.INTERNET"/>
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppStartTheme" >
            <activity
                android:name="com.liqw.demos.activity.UDPServerActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

    这样即可跑起demo做测试了。先运行服务端,再点击发送4次,服务端的log如下:

     

    参考博客:

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

    http://wang09si.blog.163.com/blog/static/170171804201303004343304/

  • 相关阅读:
    纽约顶级富婆鄙视链:4星|《我是个妈妈,我需要铂金包:一个耶鲁人类学博士的上东区育儿战争》
    2星|陈春花《顺德40年》:各种官宣的汇编,内容太虚,新信息太少
    人们喜欢传播符合自己三观的新闻,不在乎真假:4星|《环球科学》2018年12月号
    营销相关21本书
    5星|《辩论:美国制宪会议记录》:200年前的会议纪要
    3星|《品牌物理学》:理论没有实际应用案例,有推销软件的嫌疑
    关于思考的思考12本书,5星2本,4星7本
    Chrome插件 postman的使用方法详解!最全面的教程
    postman发送json请求,使用案例
    SUSE Enterprise Server 12 SP3 64 设置防火墙开放8080端口
  • 原文地址:https://www.cnblogs.com/liqw/p/4867657.html
Copyright © 2020-2023  润新知