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

Android UDP连接发送请求和接受请求的例子

2016-06-14 11:39 447 查看
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>

UDP接收服务器响应内容
<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("连接超时");
}
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: