UDP的开销小,因此用于短连接会非常方便。但缺点就是丢包,(可以辅助以一个TCP协议加以维持丢包重发)。
下面是实例代码,其实无论客户端或服务端都是差不多的,毕竟UDP更偏向于单向发送。
Android客户端:(需要注意的是安卓端需要开启相关的权限,你可以在文末附上的那篇文章里找到相关的解决方法)
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et=(EditText)findViewById(R.id.et);
bt=(Button)findViewById(R.id.btn);
bt2=(Button)findViewById(R.id.btn2);
System.out.println("启动");
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(sendMyMessage).start();//新线程,防止堵塞主线程
}
});
bt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try{
socket.close();
finish();
}
catch (Exception e){
e.printStackTrace();
}
finally {
finish();
}
}
});
}
private DatagramSocket socket;
private DatagramPacket packet;
private final String IP="192.168.1.103";
private final int ServerPORT=12345;
private final int ClientPORT=1234;
private EditText et;
private Button bt;
private Button bt2;
Runnable sendMyMessage=new Runnable() {
@Override
public void run() {
try{
socket = new DatagramSocket(ClientPORT);//本地发送窗口
//InetAddress serverIP=InetAddress.getByName(IP);
byte[] buf = "yes.".getBytes();//将你的数据转化为byte
packet = new DatagramPacket(buf,buf.length,InetAddress.getByName(IP),ServerPORT);//数据打包,服务器地址和接收窗口
socket.send(packet);/发送消息
/*接受服务器回传消息
packet = new DatagramPacket(buf,buf.length);
socket.receive(packet);*/
socket.close();//发送完就可以关闭了,防止端口占用
}catch (Exception e){
e.printStackTrace();
}
}
};
}
PC上的服务器:
import java.io.IOException;测试结果如下:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UDPTarget {
public static void main(String[] args){
DatagramSocket socket;
DatagramPacket packet;
byte[] buf = new byte[1024];
try {
socket = new DatagramSocket(12345);//注意这个12345是ServerPORT,也就是服务器监听的端口
packet = new DatagramPacket(buf, buf.length);
while(true){
socket.receive(packet);//接受数据包
System.out.println(packet.getAddress().getHostAddress()+":"+packet.getPort());//获取客户端的IP和端口
System.out.println(new String(packet.getData(), 0, packet.getLength()));
}
//socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我们可以总结这个步骤流程:
1.创建一个DatagramSocket实例:
DatagramSocket socket=new DatagramSocket();作为发送方,如果只是单纯的发送,你完全可以不指定这个Socket的监听端口,因为你根本不打算收到回传消息。
作为接收方,你必须指定这个监听的端口。
2.1发送步骤
打包数据并发送,需要知道接收方的IP和它所监听的端口:
byte[] buf = "yes.".getBytes();//这是数据2.2接收步骤
packet = new DatagramPacket(buf,buf.length,InetAddress.getByName(IP),ServerPORT);//数据打包,并发往服务器地址和接收窗口
socket.send(packet);//发送
socket = new DatagramSocket(ServerPORT);//监听端口
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);//接收
System.out.println(new String(packet.getData(), 0, packet.getLength()));//拆包
3.关闭Socket
socket.close();
相比起TCP,UDP实现起来逻辑更简单(收发方逻辑几乎是相同的),开销也更小,在一般通讯时,主要利用UDP来发送消息是个不错的选择;不过我们还需要一点辅助手段来处理UDP丢包的问题。
可以到这里查看关于TCP的实现,并进行对比:
常见问题等也见下面这篇文章的最后一段:
>Android TCP通信的简单实例以及常见问题[超时/主线程阻塞]<