TCP和UDP的区别是:
TCP协议是面向连接的,UDP是无连接的。
TCP主要是ServerSocket、Socket。UDP主要是DatagramSocket、DatagramPacket。
TCP用ServerSocket来监听收数据的端口,用Socket来建立连接,用输入输出流来通信(inputstream、outputstream)。UDP是把数据、目标IP和端口都封装在DatagramPacket中,然后由DatagramSocket发送出去。
构建DatagramSocket:
DatagramSocket():如果没有特定监听的端口,就随机使用一个临时的端口发送数据。
DatagramSocket(int port):创建实例,并固定监听Port端口的报文。
DatagramSocket实例的receive方法接收DatagramPacket,DatagramPacket中间就包含了通信的内容和目标的IP和端口。
DatagramSocket的send发送DatagramPacket
服务端代码:
package com.example.androidudptest;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends Activity {
public final static String TAG = "UDP_TEST";
public final static int SHOW_MSG = 1001;
public final static int SHOW_ERROR = 1002;
private DatagramSocket datagramSocket = null;
private DatagramPacket datagramPacket = null;
private final static int PORT = 8090;
private byte[] dataBuf;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
if(msg.what == SHOW_ERROR || msg.what == SHOW_MSG){
Toast.makeText(MainActivity.this, (String)msg.obj, Toast.LENGTH_LONG).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
dataBuf = new byte[1024];
try {
datagramSocket = new DatagramSocket(PORT);
datagramPacket = new DatagramPacket(dataBuf, dataBuf.length);
// datagramSocket.setSoTimeout(10000);
new Thread(new ReceiveRunnable()).start();
}
catch (SocketException e) {
Log.d(TAG, "init(), SocketException : ", e);
showMsg(SHOW_ERROR,"init(), SocketException");
}
}
class ReceiveRunnable implements Runnable {
public void run() {
while (true) {
try {
Log.d(TAG, "ReceiveRunnable , start receive...");
datagramPacket.setData(dataBuf);
datagramSocket.receive(datagramPacket); // 接收数据报文到datagramPacket中。receive方法产生阻塞(阻塞的时间为datagramSocket.setSoTimeout(10000)设置的时间)
int length = datagramPacket.getLength();
byte [] data = datagramPacket.getData();
String strData = new String(data,0,length);
String clientIp = datagramPacket.getAddress().getHostAddress(); // 消息发送者的IP
int clientPort = datagramPacket.getPort(); // 消息发送者的端口
Log.d(TAG, "ReceiveRunnable , strData = " + strData + ", clientIp = " + clientIp + ", clientPort = " + clientPort);
showMsg(SHOW_MSG,strData);
// 向客户端返回消息
datagramPacket.setSocketAddress(new InetSocketAddress(clientIp, clientPort));
datagramPacket.setData("nihao_client".getBytes());
datagramSocket.send(datagramPacket);
}
catch (IOException e) {
Log.d(TAG, "ReceiveRunnable , IOException : ", e);
showMsg(SHOW_ERROR,"ReceiveRunnable(), IOException");
//break;
}
}
}
}
private void showMsg(int msgWhat,String strMsg){
Message msg = mHandler.obtainMessage(msgWhat);
msg.obj = strMsg;
mHandler.sendMessage(msg);
}
}
客户单代码:
package com.java.test.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class UdpTestClient {
public static void main(String[] args){
String serverHost = "172.27.223.3";
int serverPort = 8090;
byte[] sendMsg = "服务端你好,我这里是客户端!".getBytes();
DatagramPacket datagramPacket = null;
DatagramSocket datagramSocket = null;
try {
datagramPacket = new DatagramPacket(sendMsg,
sendMsg.length,
InetAddress.getByName(serverHost),
serverPort);
//datagramSocket = new DatagramSocket(8891); // 监听本地的端口
datagramSocket = new DatagramSocket(); // 没有监听本地的端口
datagramSocket.send(datagramPacket);
/*
* 等待服务端返回来的消息
*/
datagramSocket.receive(datagramPacket) ;
int length = datagramPacket.getLength();
byte [] data = datagramPacket.getData();
String info = new String(data,0,length);
System.out.println("服务端回应数据:" + info);
}
catch (UnknownHostException e) {
e.printStackTrace();
}
catch (SocketException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}