您的位置:首页 > 理论基础 > 计算机网络

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.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" />
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  UDP通信 android tcp