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
在Activity中通过点击按钮发送和接收响应并处理响应内容
<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("连接超时"); } } } } }
相关文章推荐
- Android与JS互相调用
- android快速索引的实现
- Android各种访问权限Permission详解
- Android_menu_SubMenu
- Android EditText默认数字键盘,能输入字母和数字
- Android_menu_optionMenu
- Android项目基本结构详解
- Android实现点击AlertDialog上按钮时不关闭对话框的方法
- 关于谷歌发布的750的开源图标
- Android_Menu_contextMenu
- Fragment 与 Activity 生命周期对比
- 【Android】Lambda表达式
- android 主线程是线程不安全的
- Android 内存泄露检查之StrictMode模式
- Android 基于Bmob的聊天——用户登陆+将用户信息保存至本地
- Android 6.0 双向通话自动录音
- PinnedHeaderListView源码详解
- g++编译动态库。测试java jni调用第三方动态库。[android studio IDE]
- Android解析XML方式(三)使用DOM解析XML
- Android百度地图应用开发基础知识