UDP请求的发送
<span style="font-size:14px;">import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
import com.changhong.electric_controll.UDPResponseCallback;
import com.changhong.electric_controll.util.ByteUtils;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
public class UDPBroadCast extends Thread {
private MulticastSocket sender = null;
private DatagramSocket datagramSocket=null;
private DatagramPacket dj = null;
private InetAddress group = null;
private UDPReceiveAndTCPSend mUDPReceiveAndTCPSnd;
private UDPResponseCallback callback; //自定义接口,用于处理接收到的UDP结果,主要是调用它唯一的方法onResponse,提高结果处理的灵活性
public String LocalIP;
public int DEFAULT_PORT=12426;
private byte[] data = new byte[1024]; //用于发送udp的byte数组
private boolean isudpsendfinished=false;
private Context mContext;
public UDPBroadCast(Context context,byte[] dataString, UDPResponseCallback callback) {
mContext=context;
this.data = dataString;
this.callback=callback;
}
@Override
public void run() {
try {
if(datagramSocket==null){
datagramSocket = new DatagramSocket(null);
datagramSocket.setReuseAddress(true);
datagramSocket.bind(new InetSocketAddress(DEFAULT_PORT));
}
sender = new MulticastSocket();
LocalIP=getWIFIIP(mContext);
LocalIP=getBoradcastIP(LocalIP);
Log.i("Data","LocalIp="+LocalIP);
group = InetAddress.getByName(LocalIP); //这个是我客户端的IP地址,也可以是客户端所在的网段的广播地址,也可以是虚拟广播地址
if(data.length != 0) {
dj = new DatagramPacket(data, data.length, group,DEFAULT_PORT); //端口号可以自己随便定,发送至的端口号
datagramSocket.send(dj); //发送UDP广播
Log.i("Data", "发送的内容是" + ByteUtils.bytesToHexString(data));
datagramSocket.close();
isudpsendfinished=true;
ReUDPAndSenTCP(); //用于接收UDP响应的线程
}
} catch(IOException e) {
Log.i("Data","UDPBroadCast已经挂啦");
e.printStackTrace();
}
}
public void onStop() {
Log.i("Data","datagramSocket是否连接="+datagramSocket.isConnected()+",是否关闭="+datagramSocket.isClosed());
if (!datagramSocket.isConnected() || datagramSocket.isClosed()) {
Log.i("Data", "datagramSocket已关闭");
datagramSocket.close();
}
this.interrupt();
Log.i("Data", "线程停止");
}
public void ReUDPAndSenTCP(){
if(isudpsendfinished){
if( mUDPReceiveAndTCPSnd == null) {
mUDPReceiveAndTCPSnd = new UDPReceiveAndTCPSend(callback);
mUDPReceiveAndTCPSnd.start();
}
}
}
public 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())
{
return inetAddress.getHostAddress().toString();
}
}
}
}
catch (SocketException ex)
{
Log.e("Data","WifiPreference IpAddress"+ ex.toString());
}
return null;
}
public String getBoradcastIP(String IP){
String temp=IP.substring(0,11); //因为这是一个b类地址
Log.i("Data","temp="+temp);
StringBuffer buffer=new StringBuffer();
buffer.append(temp);
buffer.append("255");
return buffer.toString();
}
public String getWIFIIP(Context context){
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String SSID=wifiInfo.getSSID();
Log.i("Data","SSID="+SSID);
String IPAddress=intToIp(ipAddress); //获取WIFI的IP地址
return IPAddress;
}
public String intToIp(int i) {
return (( i & 0xFF)+ "."+ ((i >> 8 ) & 0xFF) + "."
+ ((i >> 16 ) & 0xFF) + "." +((i >> 24 ) & 0xFF )); }
}
</span>
<span style="font-size:14px;">import android.util.Log;
import com.changhong.electric_controll.UDPResponseCallback;
import com.changhong.electric_controll.connect.entity.entity.UDPAccept;
import com.changhong.electric_controll.connect.entity.parser.UDPDataParser;
import com.changhong.electric_controll.util.ByteUtils;
import org.apache.http.conn.util.InetAddressUtils;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;
/*接收udp多播 并 发送tcp 连接*/
public class UDPReceiveAndTCPSend extends Thread {
UDPResponseCallback mUDPResponseCallback;
public DatagramSocket datagramSocket=null;
public DatagramPacket dp;
public UDPDataParser mUDPParser;
public UDPAccept mUDPAccept;
public String mIPaddress;
public String mPort;
public int DEFAULT_PORT=12426;
public StringBuffer sb;
public UDPReceiveAndTCPSend(UDPResponseCallback callback){
this.mUDPResponseCallback=callback;
mUDPParser=new UDPDataParser();
}
@Override
public void run() {
byte[] data = new byte[1024];
try {
if(datagramSocket==null) {
datagramSocket=new DatagramSocket(null);
datagramSocket.setReuseAddress(true);
datagramSocket.bind(new InetSocketAddress(DEFAULT_PORT));
}
} catch (Exception e) {
e.printStackTrace();
}
while (true) {
try {
dp = new DatagramPacket(data, data.length);
if (datagramSocket != null) {
datagramSocket.receive(dp);
}
} catch (Exception e) {
Log.i("Data","UDPReceeive 已经挂啦");
e.printStackTrace();
}
if(dp != null){
String response= ByteUtils.bytesToHexString(dp.getData());
Log.i("Data", "UDP response = " + response);
byte[] data1=dp.getData();
mUDPAccept=mUDPParser.analysis(data1);
if(mUDPAccept != null) {
mIPaddress = mUDPParser.setIPAddress(mUDPAccept.getIPAddress());
mPort =mUDPParser.setPort(mUDPAccept.getPort());
}
Log.i("Data", "The Ip=" + mIPaddress);
Log.i("Data","The Port = "+mPort);
if (mIPaddress != null) {
final String quest_ip = dp.getAddress().toString().substring(1); //从UDP包中解析出IP地址
String host_ip = getLocalHostIp(); //若udp包的ip地址 是 本机的ip地址的话,丢掉这个包(不处理)
if ((!host_ip.equals("")) && host_ip.equals(quest_ip.substring(1))) {
continue;
}
if(mIPaddress.equals("0.0.0.0")){
mUDPResponseCallback.onResponse(null,false);
}
sb=new StringBuffer();
sb.append(mIPaddress);
sb.append(",");
sb.append(mPort);
Log.i("Data","UDP result="+sb.toString());
mUDPResponseCallback.onResponse(sb.toString(), true); //将IP地址传递回去
datagramSocket.close();
break;
}
}
}
}
public String getLocalHostIp() {
String ipaddress = "";
try {
Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
// 遍历所用的网络接口
while (en.hasMoreElements()) {
NetworkInterface nif = en.nextElement();// 得到每一个网络接口绑定的所有ip
Enumeration<InetAddress> inet = nif.getInetAddresses();
// 遍历每一个接口绑定的所有ip
while (inet.hasMoreElements()) {
InetAddress ip = inet.nextElement();
if (!ip.isLoopbackAddress()
&& InetAddressUtils.isIPv4Address(ip
.getHostAddress())) {
return ip.getHostAddress();
}
}
}
}
catch(SocketException e)
{
Log.e("Data", "获取本地ip地址失败");
e.printStackTrace();
}
return ipaddress;
}
}
</span>
用到的自定义接口 UDPResponseCallback.java
<span style="font-size:14px;">public interface UDPResponseCallback {
public void onResponse(String response,boolean isSuccess);
}</span><strong style="font-size: 12pt;">
</strong>
在Activity中通过点击按钮发送和接收响应并处理响应内容
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.support.v7.app.ActionBarActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.changhong.electric_controll.connect.entity.parser.UDPDataParser;
import com.changhong.electric_controll.util.ByteUtils;
import com.changhong.electric_controll.thread.UDPBroadCast;
import com.changhong.electric_controll.util.WifiUtil;
public class MainActivity extends ActionBarActivity implements View.OnClickListener{
private String TAG="MainActivity";
private TextView result_text;
private Button submit;
private Button cancel;
private AlertDialog wifiConfigDialig;
private ProgressDialog mProgressDialog;
public UDPBroadCast mUDPBroadCast; //UDP连接线程
public boolean ifTCPSendFinished=false; //用来判断TCP连接是否完成
public byte[] sendData; //存放发送的UDP数据
private final static int DisProcess = 0x123;
private SocketTimeCounter timeCounter; //计时器
private static final int TIME_MILLIS=60*1000;
public Handler mhandler=new Handler(){
public void handleMessage(Message msg){
switch(msg.what){
case DisProcess:
disAsynProgressDialog();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initview();
}
/**
* 初始化控件
**/
private void initview() {
//result_text = (TextView) findViewById(R.id.result);
submit = (Button) findViewById(R.id.start_config);
cancel = (Button) findViewById(R.id.cancel_config);
submit.setOnClickListener(this);
cancel.setOnClickListener(this);
}
/**发送UDP广播并接收UDP广播,从中解析出IP地址
*
* OnResponse用于处理接收到的UDP包的内容
*
* **/
public void SenUDPBroadCast(byte[] sendBytes){
if(mUDPBroadCast != null){
mUDPBroadCast.onStop();
mUDPBroadCast=null;
}
mUDPBroadCast = new UDPBroadCast(MainActivity.this,sendBytes, new UDPResponseCallback() {
@Override
public void onResponse(String response,boolean isSuccess) {
try {
if(TextUtils.isEmpty(response)){
return;
}
if(!isSuccess){
Log.i("Data","MainActivity 连接失败,请重新连接");
disAsynProgressDialog();
showToast("连接失败,请重新连接");
stopTimeCounter();
return ;
}
Log.i("Data","设置显示信息");
String IPAddress=response.split(",")[0];
String Port=response.split(",")[1];
Log.i("Data", "MainActivity IP=" + IPAddress);
Log.i("Data", "MainActivity Port=" + Port);
ifTCPSendFinished=true;
disAsynProgressDialog();
Intent intent=new Intent(MainActivity.this, ShowInfoActivity.class);
intent.putExtra(ShowInfoActivity.IPADDRESS,IPAddress);
intent.putExtra(ShowInfoActivity.PORT,Port);
startActivity(intent);
MainActivity.this.finish();
}catch(Exception e){
e.printStackTrace();
}
}
});
mUDPBroadCast.start();
}
/**
* 点击配置按钮之后的后续操作
**/
public void submit() {
//这里写对数组byte的初始化
sendData=new UDPDataParser().build();
Log.i("Data", "发送的数据是" + ByteUtils.bytesToHexString(sendData));
startTimeCounter(TIME_MILLIS,TIME_MILLIS/2); //开启计时器
SenUDPBroadCast(sendData); //开始UDP连接
showAsyncProgressDialog("正在连接设备...",true);
}
/**
* toast提示
**/
public void showToast(String toastmessage) {
Toast.makeText(this, toastmessage, Toast.LENGTH_SHORT).show();
}
/**
* 数据加载小菊花
*
* @param msg 内容
* @param isCancel 是否允许关闭 true - 允许 false - 不允许
*/
public void showAsyncProgressDialog(final String msg, final boolean isCancel) {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(MainActivity.this);
}
if (mProgressDialog.isShowing()) {
return;
}
mProgressDialog.setMessage(msg);
mProgressDialog.setCancelable(isCancel);
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.setOnCancelListener(null);
mProgressDialog.show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* 隐藏数据加载的进度小菊花
**/
public void disAsynProgressDialog() {
try {
if (mProgressDialog != null || mProgressDialog.isShowing()) {
runOnUiThread(
new Runnable() {
@Override
public void run() {
mProgressDialog.dismiss();
}
}
);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void onDestroy(){
super.onDestroy();
Log.i("Data","MainActivity 执行OnDestroy方法");
mUDPBroadCast.onStop();
stopTimeCounter();
}
/**关闭计时器**/
public void stopTimeCounter(){
if (null != timeCounter) {
Log.i("Data", "stop Timeout Counter");
timeCounter.cancel();
timeCounter = null;
}
}
/**开启计数器**/
public void startTimeCounter(int Millis,int interval){
stopTimeCounter(); //如果计时器已经开启,先关闭原来的,再重新开启
Log.i("Data","启动计时器");
timeCounter=new SocketTimeCounter(Millis,interval);
timeCounter.start();
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.start_config:
submit();
break;
case R.id.cancel_config:
break;
}
}
/**计时器**/
private class SocketTimeCounter extends CountDownTimer {
public SocketTimeCounter(int millistime,int interval){
super(millistime,interval);
}
@Override
public void onTick(long millisUntilFinished) {
}
@Override
public void onFinish() {
if(!ifTCPSendFinished){
if(!MainActivity.this.isFinishing()) {
disAsynProgressDialog();
mUDPBroadCast.onStop();
showToast("连接超时");
}
}
}
}
}