注意 :udp存在丢包问题 也不能保证每次发包都能接收到
UDP通信步骤:
1、建立连接的IP地址和端口号,IP即是你想要发送的地址,端口号则要选用闲置端口就是向8000~9000这样的端口号。
2、建立DatagramSocket sendSocket/receiveSocket ,用于发送和接受数据报文包。
3、创建报文包DatagramPacket sendPackage/receivePackage,将发送或接收的内容打包。
4、通过sendSocket.send(sendPackage)或者receiveSocket.receive(receivePackage),则完成了基于Socket的UDP通信。
大概分两部分 一个是接收端 一个发送端 ,为了方便后续数据发送接收, 各自封装成Thread, 方便操作。
直接上代码
接收端
public class ReceiveThread extends Thread {
boolean isRuning=false;
CallBack callBack=null;
DatagramSocket Receiver;
Handler mHandler=new Handler(Looper.getMainLooper());
final static String TAG = "test";
int PORT = -1;
/**
* @param port 监听端口
*/
public void setPort(int port) {
this.PORT = port;
}
public void setMessageCallback(CallBack callBack ){
this.callBack=callBack;
}
@Override
public void run() {
isRuning=true;
while (true) {
//未添加监听端口不执行
if (PORT==-1)
continue;
try {
Log.d(TAG, "run: 接收中");
byte[] buf = new byte[1024];
DatagramPacket dpReceive = new DatagramPacket(buf, buf.length);
if (Receiver == null) {
Receiver = new DatagramSocket(null);
Receiver.setReuseAddress(true);
Receiver.bind(new InetSocketAddress(PORT));
}
//设置超时时间,2秒
// Receiver.setSoTimeout(3000);
Receiver.receive(dpReceive);
DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(dpReceive.getData(), dpReceive.getOffset(), dpReceive.getLength()));
String s = inputStream.readUTF();
if (!"".equals(s)){
Log.d(TAG, "run: receive message " + s);
Log.d(TAG, "run: " + dpReceive.getAddress().toString());
if (callBack!=null){
mHandler.post(new Runnable() {
@Override
public void run() {
callBack.Message(s);
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "run: 报错" + e.getMessage());
if (callBack!=null) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (e instanceof IOException){
callBack.Error("等待接收中");
}
}
});
}
}
}
}
public interface CallBack{
public void Message(String content);
public void Error(String context);
}
}
发送端
public class SendThread extends Thread {
boolean isruning=false;
final static String TAG="test";
DatagramSocket sendSocket;
int PORT=-1;
String IP="";
//队列插入
private LinkedList<UdpData> QueueList = new LinkedList<UdpData>();
/**
*
* @param contentstr 发送内容
* @param count 发送次数
*/
public void sendMessage(String contentstr,int count){
UdpData data=new UdpData();
data.setCount(count);
data.setData(contentstr);
QueueList.add(data);
}
/**
*
* @param port 监听端口
*/
public void setPort(int port){
this.PORT=port;
}
/**
*
* @param ip 设置发送目标IP
*/
public void setIP(String ip){
this.IP=ip;
}
@Override
public void run() {
isruning=true;
while (true){
if (QueueList.size()<=0)
continue;
if (IP==null||IP.equals("")||PORT==-1)
continue;
if (QueueList.size()>0){
DatagramPacket dpSend = null;
UdpData udpData = QueueList.removeFirst();
String data = udpData.getData();
int count = udpData.getCount();
try {
InetAddress inetAddress = InetAddress.getByName(IP);
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
DataOutputStream dataOutputStream=new DataOutputStream(outputStream);
dataOutputStream.writeUTF(data);
dataOutputStream.close();
byte[] content = outputStream.toByteArray();
dpSend = new DatagramPacket(content, content.length, inetAddress, PORT);
for (int i = 0; i <count ; i++) {
sendSocket = new DatagramSocket();
sendSocket.send(dpSend);
sendSocket.close();
Log.d(TAG, "run: 发送:"+data+" 次数:"+i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
界面操作
public class UDPActivity extends AppCompatActivity {
private static final String TAG ="test" ;
Button btn_re,btn_send;
TextView et_port,et_ip,et_port_re,et_content,tv_content;
SendThread sendThread;
ReceiveThread receiveThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_u_d_p);
btn_re=findViewById(R.id.btn_re);
btn_send=findViewById(R.id.btn_send);
tv_content=findViewById(R.id.tv_content);
et_ip=findViewById(R.id.et_ip);
et_port=findViewById(R.id.et_port);
et_port_re=findViewById(R.id.et_port_re);
et_content=findViewById(R.id.et_content);
WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock lock= manager.createMulticastLock("test wifi");
sendThread=new SendThread();
sendThread.start();
receiveThread=new ReceiveThread();
receiveThread.start();
}
public void onsend(View v){
String ip = et_ip.getText().toString().trim();
String str_por = et_port.getText().toString().trim();
if ("".equals(str_por)||str_por==null)
return;
int port = Integer.parseInt(str_por);
String content= et_content.getText().toString().trim();
sendThread.setIP(ip);
sendThread.setPort(port);
sendThread.sendMessage(content,100);
}
public void onrecevie(View v){
String port_str= et_port_re.getText().toString().trim();
int port=Integer.parseInt(port_str);
receiveThread.setPort(port);
receiveThread.setMessageCallback(new ReceiveThread.CallBack() {
@Override
public void Message(String content) {
tv_content.setText(content);
}
@Override
public void Error(String context) {
tv_content.setText(context);
}
});
}
}