最近在做的项目中用到了UDP协议来通讯,整理了一下,可以与PC端网络助手之间进行测试。下面将主要功能代码写在下面供搭建参考:
UDPSocketClientManage
public class UDPSocketClientManage {
// 服务器IP
private static String SERVER_IP = "192.168.1.68";
// 服务器端口
private static int LOCAL_PORT_AUDIO = 10000;
// 接收数据包
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);
}
}
/**
* @param data :需要发送的数据
* @param len :数据字节数据
* @brief 发送数据
*/
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;
/**
* @param data :需要发送的数据
* @param len :数据字节数据
* @brief 构造函数
*/
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;
}
@SuppressLint("LongLogTag")
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;
}
}
接口SocketConnectListener
public abstract class SocketConnectListener {
// 网络状态回调
public abstract void OnConnectStatusCallBack(NetworkState networkState);
// 接收数据回调
public abstract void OnReceiverCallBack(int nLength, byte[] data);
}
网络状态枚举类NetworkState
//网络状态枚举类
public enum NetworkState {
NETWORK_STATE_NULL, // 无状态
NETWORK_STATE_CONNECT_SUCCEED, // 网络连接成功
NETWORK_STATE_DISCONNECT_SUCCEED, // 网络断开成功(自身断开)
NETWORK_STATE_SERVER_DISCONNECT, // 网络被服务器断开
NETWORK_STATE_CONNECT_FAILLD, // 连接服务器失败,IP/端口不正常
NETWORK_STATE_CONNECT_ING, // 正在连接过程中...
NETWORK_STATE_RXD, // 接收数据
NETWORK_STATE_TXD; // 发送数据
}
主页面连接使用类MainActivity
public class MainActivity extends ActionBarActivity implements View.OnClickListener {
public static UDPSocketClientManage socketClientManage = null;
// private String mstrDataString = "";
private byte[] mstrDataString;
private TextView textViewRecrive;
public static byte[] bytes1_up = {(byte) 0xfa,(byte)0x01,(byte)0x05,(byte)0x01};
@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);
mstrDataString = 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);
// textViewRecrive.setText(bytesToHexString(mstrDataString.getBytes()));
// Toast.makeText(MainActivity.this, mstrDataString, Toast.LENGTH_SHORT).show();
//下面是以16进制方式来接收
String str1 = Integer.toHexString(mstrDataString [0]& 0xFF);
String str2 = Integer.toHexString(mstrDataString [1]& 0xFF);
String str3 = Integer.toHexString(mstrDataString [2]& 0xFF);
String str4 = Integer.toHexString(mstrDataString [3]& 0xFF);
if (str1.length() == 1) {
str1='0' + str1;
}
if (str2.length() == 1) {
str2='0' + str2;
}
if (str3.length() == 1) {
str3='0' + str3;
}
if (str4.length() == 1) {
str4='0' + str4;
}
textViewRecrive.setText(str1+" "+str2+" "+str3+" "+str4);
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:
socketClientManage.send(bytes1_up, bytes1_up.length);
break;
default:
break;
}
}
}
布局.xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="本地IP地址:" />
<TextView
android:id="@+id/textViewLoca"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="40dp">
<requestFocus />
</EditText>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PC端的IP地址(也就是发送数据服务器地址):" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PC端的IP端口(也就是发送数据服务器端口):" />
<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="40dp"
android:inputType="number" >
<requestFocus />
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送给PC端的数据" />
<EditText
android:id="@+id/editText3"
android:layout_width="match_parent"
android:layout_height="40dp" >
<requestFocus />
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:text="确定" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:text="连接" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送" />
</LinearLayout>
<TextView
android:id="@+id/textViewRecrive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="接收到的数据:" />
</LinearLayout>
最后别忘了在AndroidManifest.xml里添加权限
<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" />
以上这些就是全部代码,有不足指出还请大家指出
下面为大家附上源码