您的位置:首页 > 移动开发 > Android开发

android udp与pc端通信实例

2016-12-18 12:00 555 查看
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端的调试工具。
最后需要注意的是(据热心博友评论中的总结):
要在同一个网关才能连接,不管是udp还是tcp协议
例:192.168.1.22
192.168.2.12
前面的网关为1,后面的网关为2,所以不能连接,需要修改网关使其相同,连接成功。

本博客的项目下载(里面有源码以及pc网络调试助手):http://download.csdn.net/detail/qq_16064871/9714545
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: