Java实现UDP通信

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();
		}
    }    
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现JavaUDP通信,可以通过以下步骤: 1. 创建一个DatagramSocket对象,指定本地端口号。例如: ``` DatagramSocket socket = new DatagramSocket(8888); ``` 2. 创建一个DatagramPacket对象,用于发送和接收数据。例如: ``` byte[] sendData = "Hello, world!".getBytes(); InetAddress address = InetAddress.getByName("127.0.0.1"); int port = 9999; DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port); ``` 3. 发送数据。使用DatagramSocket的send()方法发送数据。例如: ``` socket.send(sendPacket); ``` 4. 接收数据。使用DatagramSocket的receive()方法接收数据。例如: ``` byte[] receiveData = new byte[1024]; DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); socket.receive(receivePacket); String receiveMessage = new String(receivePacket.getData(), 0, receivePacket.getLength()); ``` 完整的代码示例: ``` import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UDPExample { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(8888); byte[] sendData = "Hello, world!".getBytes(); InetAddress address = InetAddress.getByName("127.0.0.1"); int port = 9999; DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port); socket.send(sendPacket); byte[] receiveData = new byte[1024]; DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); socket.receive(receivePacket); String receiveMessage = new String(receivePacket.getData(), 0, receivePacket.getLength()); System.out.println("Received message: " + receiveMessage); socket.close(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值