UDP通信
2016-01-28 15:10
417 查看
代码下载地址:http://download.csdn.net/detail/u011324501/9420980
UDP和TCP均指通信协议,那么,既然代表通信协议,UDP和TCP都是建立一个“通道”就可以进行服务端/客户端间的数据收发。它们的区别主要在于:UDP协议是面向非连接(不可靠)的传输协议,也就是不需要与服务端建立连接,就直接将数据发送给服务端,同时,无机制保证这条数据已成功发送给服务端。TCP协议是面向连接(可靠)的传输协议,在客户端向服务器端传输数据之前,客户端必须与服务器端通过“三次握手”来完成连接的建立,在之后的数据传输过程中,为了可靠传输,接受方还会发送ACK包来使发送方获知该数据包已经成功发送,否则,发送端将重新发送数据包直至超时或发送成功。因此,无论UDP协议还是TCP协议,均要有一个服务端先行监听某端口才能服务。
布局文件代码:<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF66FF"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/ip"/>
<EditText
android:id="@+id/etremoteip"
android:layout_width="fill_parent"
android:inputType="none"
android:layout_height="wrap_content"
android:text="@string/ipaddress"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/port" />
<EditText
android:id="@+id/etremoteport"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLength="5"
android:text="@string/remote"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/localport"/>
<EditText
android:id="@+id/etlocalport"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLength="5"
android:text="@string/local"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/receivedate"
android:layout_width="fill_parent"
android:layout_height="134dp"
android:inputType="none" />
<EditText
android:id="@+id/senddate"
android:inputType="none"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btnsend"
android:text="@string/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="@+id/ipaddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!-- 连接按钮 -->
<LinearLayout
android:layout_marginTop="15dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btnconnect"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/connect" />
<Button
android:layout_marginLeft="5dip"
android:id="@+id/btndisconnect"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/disconnect"/>
</LinearLayout>
</LinearLayout>
udpthread.java代码:
package app.udp;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Process;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private EditText etremoteip;
private EditText etremoteport;
private EditText etlocalport;
private EditText etrdata;
private EditText etsdata;
private Button btnconnect;
private Button btndisconnect;
private Button btnsend;
private TextView ipaddress;
public static MainActivity mainActivity;
boolean flag = false;
private udpthread ut = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainActivity = this;
initUI();
}
//初始化ui
private void initUI()
{
etremoteip = (EditText)findViewById(R.id.etremoteip);
etremoteport = (EditText)findViewById(R.id.etremoteport);
etlocalport = (EditText)findViewById(R.id.etlocalport);
etrdata = (EditText)findViewById(R.id.receivedate);
etrdata.setMovementMethod(ScrollingMovementMethod.getInstance());
etsdata = (EditText)findViewById(R.id.senddate);
ipaddress = (TextView)findViewById(R.id.ipaddress);
ipaddress.setText("手机ip地址:"+getIP());
btnconnect = (Button)findViewById(R.id.btnconnect);
btnconnect.setOnClickListener(this);
btndisconnect = (Button)findViewById(R.id.btndisconnect);
btndisconnect.setOnClickListener(this);
btnsend = (Button)findViewById(R.id.btnsend);
btnsend.setOnClickListener(this);
ut = new udpthread(etrdata);
}
@Override
public void onClick(View v)
{
if (v.equals(btnconnect))//点击连接
{
String RemoteIP = etremoteip.getText().toString().trim();//IP
int RemotePort = Integer.parseInt(etremoteport.getText().toString().trim());//远程端口号
int LocalPort = Integer.parseInt(etlocalport.getText().toString().trim());//本地端口号
ut.setRemoteIP(RemoteIP);
ut.setRemotePort(RemotePort);
ut.setLocalPort(LocalPort);
ut.setCurrentRCodes("UTF-8");//设置接收数据格式
ut.setCurrentSCodes("UTF-8");//设置发送数据格式
if (ut.ConnectSocket()){
flag = true;
btnconnect.setEnabled(false);
btndisconnect.setEnabled(true);
Toast.makeText(getApplication(), "已连接!", Toast.LENGTH_SHORT).show();
}
}
if (v.equals(btndisconnect))//断开连接
{
try{
btndisconnect.setEnabled(false);
btnconnect.setEnabled(true);
Toast.makeText(getApplication(), "连接已断开!", Toast.LENGTH_SHORT).show();
ut.DisConnectSocket();
}catch(Exception e){
e.printStackTrace();
}
}
if (v.equals(btnsend))//发送
{
String date = etsdata.getText().toString().trim();
if (!date.trim().equals("") && flag ){
ut.SendData(date);
}else{
Toast.makeText(getApplication(), "请连接或输入数据!", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onDestroy()
{
super.onDestroy();
Process.killProcess(Process.myPid());
}
/**
* 获取ip地址
* @return ipaddress
*/
public String getIP(){
//获取wifi服务
WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
//判断wifi是否打开
if(!wifiManager.isWifiEnabled()){
wifiManager.setWifiEnabled(true);
}
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ip = intToIp(ipAddress);
return ip;
}
/**
*
* @param i
* @return
*/
private String intToIp(int i) {
// TODO Auto-generated method stub
return (i & 0xFF) + "."+
((i>>8) & 0xFF) + "."+
((i>>16) & 0XFF) + "." +
((i>>24) & 0xFF) ;
}
}
权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
UDP和TCP均指通信协议,那么,既然代表通信协议,UDP和TCP都是建立一个“通道”就可以进行服务端/客户端间的数据收发。它们的区别主要在于:UDP协议是面向非连接(不可靠)的传输协议,也就是不需要与服务端建立连接,就直接将数据发送给服务端,同时,无机制保证这条数据已成功发送给服务端。TCP协议是面向连接(可靠)的传输协议,在客户端向服务器端传输数据之前,客户端必须与服务器端通过“三次握手”来完成连接的建立,在之后的数据传输过程中,为了可靠传输,接受方还会发送ACK包来使发送方获知该数据包已经成功发送,否则,发送端将重新发送数据包直至超时或发送成功。因此,无论UDP协议还是TCP协议,均要有一个服务端先行监听某端口才能服务。
布局文件代码:<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF66FF"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/ip"/>
<EditText
android:id="@+id/etremoteip"
android:layout_width="fill_parent"
android:inputType="none"
android:layout_height="wrap_content"
android:text="@string/ipaddress"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/port" />
<EditText
android:id="@+id/etremoteport"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLength="5"
android:text="@string/remote"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/localport"/>
<EditText
android:id="@+id/etlocalport"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLength="5"
android:text="@string/local"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/receivedate"
android:layout_width="fill_parent"
android:layout_height="134dp"
android:inputType="none" />
<EditText
android:id="@+id/senddate"
android:inputType="none"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btnsend"
android:text="@string/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="@+id/ipaddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!-- 连接按钮 -->
<LinearLayout
android:layout_marginTop="15dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btnconnect"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/connect" />
<Button
android:layout_marginLeft="5dip"
android:id="@+id/btndisconnect"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/disconnect"/>
</LinearLayout>
</LinearLayout>
udpthread.java代码:
package app.udp; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.widget.EditText; import android.widget.Toast; import java.io.IOException; import java.net.*; //import java.util.Date; //import java.text.SimpleDateFormat; public class udpthread implements Runnable { private EditText etshowrdata = null; private String sRecvData; private Thread rthread = null;// 接收数据线程 private DatagramSocket sUdp = null;// 发送数据Socket private DatagramSocket rUdp = null;// 接收数据Socket private DatagramPacket sPacket = null; private DatagramPacket rPacket = null; private String remoteIP; private int remotePort, localPort; private boolean isSHex = false; private boolean isRHex = false; private String currentSCodes = "UTF-8"; private String currentRCodes = "UTF-8"; private byte[] rBuffer = new byte[1024];//接收数据缓存1024字节 private byte[] fBuffer = null; private byte[] sBuffer = null; //private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); private Handler vhandler = new Handler() { @Override public void handleMessage(Message msg) { if (etshowrdata != null) { if (sRecvData==null) return; StringBuilder sb = new StringBuilder(); sb.append(etshowrdata.getText().toString().trim()); sb.append("\n"); sb.append(sRecvData); etshowrdata.setText(sb.toString().trim()); sb.delete(0, sb.length()); sb = null; } // super.handleMessage(msg); } }; public udpthread(EditText et) { etshowrdata = et; } public void setRemoteIP(String remoteIP) { this.remoteIP = remoteIP; } public void setRemotePort(int remotePort) { this.remotePort = remotePort; } public void setLocalPort(int localPort) { this.localPort = localPort; } public void setSHex(boolean isSHex) { this.isSHex = isSHex; } public void setRHex(boolean isRHex) { this.isRHex = isRHex; } public void setCurrentSCodes(String currentSCodes) { this.currentSCodes = currentSCodes; } public void setCurrentRCodes(String currentRCodes) { this.currentRCodes = currentRCodes; } private void startThread() { if (rthread == null) { rthread = new Thread(this); rthread.start(); } } @SuppressWarnings("deprecation") private void stopThread() { if (rthread != null) { rthread.stop(); rthread = null; } } @Override public void run() { while (Thread.currentThread() == rthread) { try { //不加报RuntimeException,原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。 Looper.prepare();// recvData(); vhandler.sendEmptyMessage(0); Thread.sleep(100); Looper.loop(); } catch (InterruptedException e) { e.printStackTrace(); } } } private String recvHexData(int len) { fBuffer = new byte[len]; System.arraycopy(rBuffer, 0, fBuffer, 0, len); StringBuilder sb = new StringBuilder(fBuffer.length); String rHex = ""; for (int i = 0; i < fBuffer.length; i++) { rHex = Integer.toHexString(fBuffer[i] & 0xFF); if (rHex.length() == 1) rHex = "0" + rHex; sb.append(rHex.toUpperCase()); } return sb.toString().trim(); } private void recvData() { try { rUdp.receive(rPacket); if (isRHex) sRecvData = recvHexData(rPacket.getLength()); else sRecvData = new String(rPacket.getData(),currentRCodes).trim(); //sRecvData = String.format("[%s:%d//%s]%s", rPacket.getAddress().getHostAddress(), rPacket.getPort(), sdf.format(new Date()), sRecvData); sRecvData = String.format("%s", sRecvData); } catch (IOException ie) { System.out.println("recvdata error:" + ie.getMessage()); Toast.makeText(MainActivity.mainActivity, "接收数据错误:" + ie.getMessage(), Toast.LENGTH_LONG); } } private boolean CharInRange(char c) { boolean result = false; if (c >= '0' && c <= '9') result = true; if (c >= 'a' && c <= 'f') result = true; if (c >= 'A' && c <= 'F') result = true; return result; } private byte StrToByte(String s) { return Integer.valueOf(String.valueOf(Integer.parseInt(s, 16))).byteValue(); } private void SendHexData(String SData) { int datalen = SData.getBytes().length; int bytelen = 0; if ((datalen % 2)==0) bytelen = (int)(datalen / 2); else bytelen = (int)(datalen / 2) + 1; sBuffer = new byte[bytelen]; int i = 0, j = 0; while (i < datalen) { while (i >= 0 && (!CharInRange(SData.charAt(i)))) i++; if (((i + 1) >= datalen) || (!CharInRange(SData.charAt(i + 1)))) { sBuffer[j] = StrToByte(String.valueOf(SData.charAt(i))); j++; } else { sBuffer[j] = StrToByte(SData.substring(i, i + 2)); j++; } i += 2; } } public void SendData(String SData) { try { if (sUdp==null) sUdp = new DatagramSocket(); if (isSHex) SendHexData(SData); else sBuffer = SData.getBytes(currentSCodes); sPacket = new DatagramPacket(sBuffer,sBuffer.length,InetAddress.getByName(remoteIP),remotePort); sUdp.send(sPacket); sUdp.close(); sUdp = null; sPacket = null; }catch(IOException ie) { sUdp.close(); sUdp = null; sPacket = null; System.out.println("senddata error:" + ie.getMessage()); } } public boolean ConnectSocket() { boolean result = false; try { if (rUdp == null) rUdp = new DatagramSocket(localPort); if (rPacket == null) rPacket = new DatagramPacket(rBuffer, rBuffer.length); startThread(); result = true; } catch (SocketException se) { DisConnectSocket(); System.out.println("open udp port error:" + se.getMessage()); } return result; } public void DisConnectSocket() { if (rUdp != null) { rUdp.close(); rUdp = null; } if (rPacket != null) rPacket = null; stopThread(); } }mainActivity.java代码
package app.udp;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Process;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private EditText etremoteip;
private EditText etremoteport;
private EditText etlocalport;
private EditText etrdata;
private EditText etsdata;
private Button btnconnect;
private Button btndisconnect;
private Button btnsend;
private TextView ipaddress;
public static MainActivity mainActivity;
boolean flag = false;
private udpthread ut = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainActivity = this;
initUI();
}
//初始化ui
private void initUI()
{
etremoteip = (EditText)findViewById(R.id.etremoteip);
etremoteport = (EditText)findViewById(R.id.etremoteport);
etlocalport = (EditText)findViewById(R.id.etlocalport);
etrdata = (EditText)findViewById(R.id.receivedate);
etrdata.setMovementMethod(ScrollingMovementMethod.getInstance());
etsdata = (EditText)findViewById(R.id.senddate);
ipaddress = (TextView)findViewById(R.id.ipaddress);
ipaddress.setText("手机ip地址:"+getIP());
btnconnect = (Button)findViewById(R.id.btnconnect);
btnconnect.setOnClickListener(this);
btndisconnect = (Button)findViewById(R.id.btndisconnect);
btndisconnect.setOnClickListener(this);
btnsend = (Button)findViewById(R.id.btnsend);
btnsend.setOnClickListener(this);
ut = new udpthread(etrdata);
}
@Override
public void onClick(View v)
{
if (v.equals(btnconnect))//点击连接
{
String RemoteIP = etremoteip.getText().toString().trim();//IP
int RemotePort = Integer.parseInt(etremoteport.getText().toString().trim());//远程端口号
int LocalPort = Integer.parseInt(etlocalport.getText().toString().trim());//本地端口号
ut.setRemoteIP(RemoteIP);
ut.setRemotePort(RemotePort);
ut.setLocalPort(LocalPort);
ut.setCurrentRCodes("UTF-8");//设置接收数据格式
ut.setCurrentSCodes("UTF-8");//设置发送数据格式
if (ut.ConnectSocket()){
flag = true;
btnconnect.setEnabled(false);
btndisconnect.setEnabled(true);
Toast.makeText(getApplication(), "已连接!", Toast.LENGTH_SHORT).show();
}
}
if (v.equals(btndisconnect))//断开连接
{
try{
btndisconnect.setEnabled(false);
btnconnect.setEnabled(true);
Toast.makeText(getApplication(), "连接已断开!", Toast.LENGTH_SHORT).show();
ut.DisConnectSocket();
}catch(Exception e){
e.printStackTrace();
}
}
if (v.equals(btnsend))//发送
{
String date = etsdata.getText().toString().trim();
if (!date.trim().equals("") && flag ){
ut.SendData(date);
}else{
Toast.makeText(getApplication(), "请连接或输入数据!", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onDestroy()
{
super.onDestroy();
Process.killProcess(Process.myPid());
}
/**
* 获取ip地址
* @return ipaddress
*/
public String getIP(){
//获取wifi服务
WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
//判断wifi是否打开
if(!wifiManager.isWifiEnabled()){
wifiManager.setWifiEnabled(true);
}
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ip = intToIp(ipAddress);
return ip;
}
/**
*
* @param i
* @return
*/
private String intToIp(int i) {
// TODO Auto-generated method stub
return (i & 0xFF) + "."+
((i>>8) & 0xFF) + "."+
((i>>16) & 0XFF) + "." +
((i>>24) & 0xFF) ;
}
}
权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories