Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

android udp与pc端通信实例

$
0
0

udp通信还是必备知识的,最近花时间去调通了一个例子程序,还不错。包括android程序以及网络调试助手。pc的网络调试助手稂莠不齐,不好弄。我推荐一个网络调试助手。名字就叫网络调试助手,英文名称NetAssist。

1,测试环境

android 4.4真机,window 10系统

网络调试助手适配版本window all

2,网络调试助手指南

百度经验地址:http://jingyan.baidu.com/article/fea4511a70803af7bb91258a.html

界面如下:


支持TCP服务端,客户端调试;UDP服务器,客户端调试。

3,android udp客户端连接类

package com.udp.client;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import android.annotation.SuppressLint;
import android.util.Log;

public class UDPSocketClientManage {
	// 服务器IP
	private static String SERVER_IP = "192.168.1.100";
	// 服务器端口
	private static int LOCAL_PORT_AUDIO = 5052;
	// 接收数据包
	private DatagramPacket Packet_Receive;
	// 端口
	private DatagramSocket msocketClient;

	NetworkState mLastNetworkState = NetworkState.NETWORK_STATE_NULL;
	SocketConnectListener mConnectListener = null;

	// 设置网络连接参数
	public void setNetworkParameter(String strIP, int nPort) {
		SERVER_IP = strIP;
		LOCAL_PORT_AUDIO = nPort;
	}

	// 注册接收连接状态和数据的回调函数
	public void RegSocketConnectListener(SocketConnectListener listener) {
		mConnectListener = listener;
	}

	/**
	 * 启动连接服务器
	 */
	public void Connect() {
		// 正在开始连接
		mLastNetworkState = NetworkState.NETWORK_STATE_CONNECT_ING;

		try {
			// 端口
			msocketClient = new DatagramSocket(LOCAL_PORT_AUDIO);
			// 接收数据缓存
			byte[] Buffer_Receive = new byte[1024];
			// 接收包
			Packet_Receive = new DatagramPacket(Buffer_Receive,1024);

			mLastNetworkState = NetworkState.NETWORK_STATE_CONNECT_SUCCEED;

		} catch (IOException e) {
			mLastNetworkState = NetworkState.NETWORK_STATE_CONNECT_FAILLD;
			Log.e("Show", e.toString());
			e.printStackTrace();
		} catch (Exception e) {
			mLastNetworkState = NetworkState.NETWORK_STATE_CONNECT_FAILLD;
			Log.e("Show", e.toString());
			e.printStackTrace();
		}

		// 向回调发数据
		if (null != mConnectListener) {
			mConnectListener.OnConnectStatusCallBack(mLastNetworkState);
		}
		
		if (msocketClient != null) {
			new Thread(reRunnable).start();
		}
	}
	
	Runnable reRunnable = new Runnable() {
		@SuppressLint("NewApi") @Override
		public void run() {
			while (true) {
				try {
					// 接收数据
					if (Packet_Receive != null) {
					msocketClient.receive(Packet_Receive);

					// 判断数据是否合法
					InetSocketAddress address = (InetSocketAddress) Packet_Receive.getSocketAddress();
					// 判断是否是调度服务器的ip
					if (!address.getHostName().equals(SERVER_IP)) {
						continue;
					}
					// 判断是否是调度服务器的端口
					if (address.getPort() != LOCAL_PORT_AUDIO) {
						continue;
					}
					
					int length = Packet_Receive.getLength();
					if (length > 0) 
						mConnectListener.OnReceiverCallBack(length, Packet_Receive.getData());
					}
	
				} catch (IOException  e) {
					e.printStackTrace();
					Log.e("Show", e.toString());
				}
			}
		}
	};

	/**
	 * 断开连接
	 */
	public void Close() {
		if (msocketClient != null) {
			msocketClient = null;
			mLastNetworkState = NetworkState.NETWORK_STATE_DISCONNECT_SUCCEED;
			mConnectListener.OnConnectStatusCallBack(mLastNetworkState);
		}
	}
	
	/**
	 * @brief 发送数据
	 * @param data
	 *            :需要发送的数据
	 * @param len
	 *            :数据字节数据
	 */
	public void send(byte[] data, int len) {
		Thread_Send thread_send = new Thread_Send(data, len);
		new Thread(thread_send).start();
	}
	
	/**
	 * @brief 发送线程
	 */
	private class Thread_Send implements Runnable {
		// 发送数据缓存
		private byte[] Buffer_Send = new byte[1024];
		// 发送数据包
		private DatagramPacket Packet_Send;

		/**
		 * @brief 构造函数
		 * @param data
		 *            :需要发送的数据
		 * @param len
		 *            :数据字节数据
		 */
		public Thread_Send(byte[] data, int len) {
			// 发送包
			Packet_Send = new DatagramPacket(Buffer_Send,1024);
			Packet_Send.setData(data);
			Packet_Send.setLength(len);
		}

		@Override
		public void run() {
			try {
				Packet_Send.setPort(LOCAL_PORT_AUDIO);
				Packet_Send.setAddress(InetAddress.getByName(SERVER_IP));
				if (msocketClient != null) {
					msocketClient.send(Packet_Send);
					mLastNetworkState = NetworkState.NETWORK_STATE_TXD;
					mConnectListener.OnConnectStatusCallBack(mLastNetworkState);
				}else {
					mLastNetworkState = NetworkState.NETWORK_STATE_NULL;
					mConnectListener.OnConnectStatusCallBack(mLastNetworkState);
				}

			} catch (UnknownHostException e) {
				e.printStackTrace();
				mLastNetworkState = NetworkState.NETWORK_STATE_NULL;
				mConnectListener.OnConnectStatusCallBack(mLastNetworkState);
			} catch (IOException e) {
				e.printStackTrace();
				mLastNetworkState = NetworkState.NETWORK_STATE_NULL;
				mConnectListener.OnConnectStatusCallBack(mLastNetworkState);
			}
		}
	}

	// 获取最后的网络状态
	public NetworkState getLastNetworkState() {
		return mLastNetworkState;
	}
	
	public static String getLocalIpAddress() {
		try {
			for (Enumeration<NetworkInterface> en = NetworkInterface
					.getNetworkInterfaces(); en.hasMoreElements();) {
				NetworkInterface intf = en.nextElement();
				for (Enumeration<InetAddress> enumIpAddr = intf
						.getInetAddresses(); enumIpAddr.hasMoreElements();) {
					InetAddress inetAddress = enumIpAddr.nextElement();
					if (!inetAddress.isLoopbackAddress()
							&& !inetAddress.isLinkLocalAddress()) {
						return inetAddress.getHostAddress().toString();
					}
				}
			}
		} catch (SocketException ex) {
			Log.e("WifiPreference IpAddress", ex.toString());
		}
		return null;
	}
}


4,界面以及调用方法

package com.example.udpdemo;

import com.udp.client.NetworkState;
import com.udp.client.UDPSocketClientManage;
import com.udp.client.SocketConnectListener;

import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public class MainActivity extends ActionBarActivity implements OnClickListener{
	 UDPSocketClientManage socketClientManage = null;
	 private String mstrDataString="";
	 private TextView textViewRecrive;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        
        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
        findViewById(R.id.button3).setOnClickListener(this);
        TextView loTextView = (TextView)findViewById(R.id.textViewLoca);
        
        //手机端的连接路由之后IP地址,网络调试助手向目标主机发送的IP地址就是这里获取出来的
        String strLoString = UDPSocketClientManage.getLocalIpAddress();
        if (strLoString != null) {
        	  loTextView.setText(strLoString);
		}
        textViewRecrive = (TextView)findViewById(R.id.textViewRecrive);
      
        socketClientManage  = new UDPSocketClientManage();
        socketClientManage.RegSocketConnectListener(new SocketConnectListener() {
			
			@Override
			public void OnReceiverCallBack(int nLength, byte[] data) {
				mstrDataString = new String(data);
				mHandler.sendEmptyMessage(1);
			}
			
			@Override
			public void OnConnectStatusCallBack(NetworkState networkState) {
				switch (networkState) {
				case NETWORK_STATE_CONNECT_SUCCEED:
					mHandler.sendEmptyMessage(0);
					break;

				default:
					break;
				}
				
			}
		});
    }
    
  

	Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case 0: // 接受到消息之后,对UI控件进行修改
				Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_SHORT).show();
				break;		
			case 1: // 接受到消息之后,对UI控件进行修改
				textViewRecrive.append(mstrDataString);
				Toast.makeText(MainActivity.this, mstrDataString, Toast.LENGTH_SHORT).show();
				break;

			default:
				break;
			}
		}

	};
    
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.button1:
			new Thread(new Runnable() {
				@Override
				public void run() {
					socketClientManage.Connect();
					
				}
			}).start();
			
			break;
		case R.id.button2:
			EditText ipEditText = (EditText)findViewById(R.id.editText1);
			EditText porText = (EditText)findViewById(R.id.editText2);
			String ipString = ipEditText.getText().toString().trim();
			String portString = porText.getText().toString().trim();
			socketClientManage.setNetworkParameter(ipString, portString != null ? Integer.parseInt(portString) : 0);
			Toast.makeText(MainActivity.this, "设置成功", Toast.LENGTH_SHORT).show();
			break;
		case R.id.button3:
			EditText sendEditText = (EditText)findViewById(R.id.editText3);
			String sendDataString = sendEditText.getText().toString().trim();
			if(sendDataString != null)
			socketClientManage.send(sendDataString.getBytes(), sendDataString.getBytes().length);
			break;
		default:
			break;
		}
		
	}



}


5,记得权限

    <uses-permission android:name="android.permission.ACCESS_WIFI_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.INTERNET" />


6,实现效果如下

7,总结

首先明确概念,就是通信流程。同一个路由器中,你pc连上路由获取的ip地址,跟移动端连接路由获取的ip地址是不一样的,只不过网段是一样的。

这个时候就要确定相对而言的目标ip地址以及端口的概念。pc端发送,就是往移动端的ip,端口地址发送。移动端就是反过来了。

还有就是好的pc端的调试工具。

本博客的项目下载(里面有源码以及pc网络调试助手):http://download.csdn.net/detail/qq_16064871/9714545

作者:qq_16064871 发表于2016/12/18 12:00:49 原文链接
阅读:140 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles