参考,感谢两位大哥的文章
http://www.cnblogs.com/liqw/p/4867657.html
https://blog.csdn.net/u012106397/article/details/51492867
udp很早就听说过,但是由于其是面向无连接的协议,因此一直很少用到。但是在一些即时通讯方面,由于对延时有较高的要求,因此还是会使用到。
1.Android 发送udp消息
首先呢,java使用DatagramSocket来发送消息,消息的内容就放在DatagramPacket中。
package com.example.udpsender;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//来源:http://www.cnblogs.com/liqw/p/4867657.html
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private Button mBtnSendUdpMessage;
private DatagramSocket socket = null;
private InetAddress serverAddress = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
//自己的发送端口
socket = new DatagramSocket(12345); //①
//对方的ip
serverAddress = InetAddress.getByName("192.168.1.54"); //②
} catch (Exception e) {
e.printStackTrace();
}
mBtnSendUdpMessage = findViewById(R.id.btn_send_udp_message);
mBtnSendUdpMessage.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_send_udp_message:
sendMessage();
break;
}
}
private void sendMessage() {
new Thread(new Runnable() {
@Override
public void run() {
try {
String sendData = "hello world";
byte data[] = sendData.getBytes();
//这里的8888是接收方的端口号
Log.d(TAG, "run: 发送消息");
DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, 8888); //③
socket.send(packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
(1)布局上就是一个按钮,用来发送消息,就不发了。
(2)在①处new了一个socket,这里的端口12345是直接发送udp消息的端口,同时也是自己监听udp消息的端口,下面的192.168.1.54 是对方的ip
(3)在子线程中new了一个DatagramPacket对象,里面包含了具体的数据和对方的端口8888.
2.服务器端接受udp消息
首先要新建一个java项目,(居然连web项目也不需要,重点还是刚刚提到的那两个包)
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
private String message = "";
private String send = "";
public static void main(String[] args) throws IOException {
UDPServer udpServer = new UDPServer();
udpServer.receiveUdpMessage();
}
private void receiveUdpMessage() {
//http://www.cnblogs.com/liqw/p/4867657.html
System.out.println("开始----------------------------");
DatagramSocket socket = null;
try {
//若发送消息,则使用8888端口
socket = new DatagramSocket(8888);
} catch (Exception e) {
e.printStackTrace();
}
while (true) {
try {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
socket.receive(packet);
System.out.println(packet.getAddress()); // /ip
System.out.println(packet.getPort()); //端口
System.out.println(packet.getSocketAddress()); // /ip:端口
message = new String(packet.getData(), packet.getOffset(), packet.getLength());
send = message;
System.out.println("receive client's data: " + message);
if (!send.equals("")) {
sendUdpMessage();
send = "";
}
// System.out.println("receive client's data: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void sendUdpMessage() {
//https://blog.csdn.net/u012106397/article/details/51492867
new Thread(() -> {
try {
DatagramSocket dgSocket = new DatagramSocket();
System.out.println("发送消息:" + message);
byte[] data = message.getBytes();
DatagramPacket dgPacket = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.1.62"), 12345);
dgSocket.send(dgPacket);
dgSocket.close();
System.out.println("send message is ok.");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
(1)和上面一样,监听自己的8888端口,
(2)用一个while的循环来获取需要打印的消息,这个receiveUdpMessage方法里面还顺便打印了ip和端口,可以看到客户端的ip和端口
(3)下面的sendUdpMessage方法可以将消息利用udp发送到客户端
3.Android 接受udp消息
package com.example.udpreceiver;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, UdpReceiverService.class);
Log.v("WANGRUI", "准备启动service...............");
startService(intent);
Log.v("WANGRUI", "开启service...............");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.v("WANGRUI", "stopservice 被调用。。。。。。。。。");
Intent intent = new Intent(this, UdpReceiverService.class);
stopService(intent);
}
}
(1)接收端界面什么都没有,MainActivity就是开启了一个服务来接受消息
package com.example.udpreceiver;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
//https://blog.csdn.net/u012106397/article/details/51492867
public class UdpReceiverService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread() {
public void run() {
while (true) {
try {
DatagramSocket dgSocket = null;
int port = 12345;
dgSocket = new DatagramSocket(null);
dgSocket.setReuseAddress(true);
dgSocket.bind(new InetSocketAddress(port));
byte[] by = new byte[1024];
DatagramPacket packet = new DatagramPacket(by, by.length);
dgSocket.receive(packet);
String str = new String(packet.getData(), 0, packet.getLength());
System.out.println("接收到的数据为:" + str);
Log.v("WANGRUI", "已获取服务器端发过来的数据。。。。。" + str);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
最后再次感谢两位大哥的文章
http://www.cnblogs.com/liqw/p/4867657.html
https://blog.csdn.net/u012106397/article/details/51492867