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 查看评论