JAVA Socket网络编程------UDP

本文详细介绍了Java中使用UDP协议进行通信的实践,包括DatagramSocket和DatagramPacket的使用方法,以及如何实现局域网内主机之间的消息传递,展示了发送方与接收方的代码实例和通信过程。
摘要由CSDN通过智能技术生成

一、什么是UDP?

TCP是建立可靠连接,并且通信双方都可以以流的形式发送数据。相对TCP,UDP则是面向无连接的协议。

使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。

虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。

 

二、JAVA相关API

2.1 DatagramSocket: (创建Socket)

 

DatagramSocket创建例子(20000是绑定的端口):

DatagramSocket ds = new DatagramSocket(20000);

2.2 DatagramPacket: (把要发送或接收的数据都封装到DatagramPacket中,然后由DatagramSocket发送或接收)

getAddress():获得DatagramPacket中的IP地址。

getPort():获得DatagramPacket中的I端口号。

DatagramPacket其实就是构建一个包,包里面有内容,有目标的IP,目标的端口号。

接收数据代码:

byte[] buf = new byte[512];  //接收数据的缓冲区
DatagramPacket receivePack = new DatagramPacket(buf, buf.length);//包装
ds.receive(receivePack); //通过DatagramSocket的receive方法把数据写进receivePack中

发送和接收的代码:

        //接收缓存
        final byte[] buf = new byte[512];
        DatagramPacket receivePack = new DatagramPacket(buf,buf.length);
        //接收来自发送方的数据data
        ds.receive(receivePack);

        //构建回送数据
        String responeData = "Receive data with len:"+dataLen;
        byte[] responseDataBytes = responeData.getBytes();
        DatagramPacket responsePacket = new DatagramPacket(responseDataBytes,
                responseDataBytes.length,receivePack.getAddress(),receivePack.getPort());
        ds.send(responsePacket);

 

三、UDP通信例子:

3.1 局域网搜索

步骤:

1.主机B(提供方)监听本机的20000端口。

2. A电脑(搜索方,搜索局域网内监听20000端口的主机) 向 局域网内的 计算机的20000端口发送消息。(假设A的发送端口是10000)

3.  这时候B电脑会收到A电脑的消息(B收到消息后,就可以确认A的端口了),如果A电脑监听本机的10000端口,如果B往10000端口发送数据,A也会收到B的消息。

4. 这样就实现了信息的交互。

下面这个代码是提供方的代码,会等待一次发送方的数据并接收,如果没有发送方发送数据,会阻塞。

提供方:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPProvider {
    public static void main(String[] args) throws IOException {
        System.out.println("UDPProvider started");
        //绑定20000端口
        DatagramSocket ds = new DatagramSocket(20000);
        //接收信息的实体
        final byte[] buf = new byte[512];
        DatagramPacket receivePack = new DatagramPacket(buf,buf.length);
        //监听绑定的端口并准备接收(下面这条语句会阻塞,一定等待有发送方来发数据为止)
        ds.receive(receivePack);
        //打印发送者的信息
        String ip = receivePack.getAddress().getHostAddress();//发送方IP
        int port = receivePack.getPort(); //发送方的端口
        int dataLen = receivePack.getLength(); //数据长度
        String data = new String(receivePack.getData(),0,dataLen);
        System.out.println("receive from IP:"+ip+" port:"+port
                +"\t"+"data:"+data);
        //构建回送数据
        String responeData = "Receive data with len:"+dataLen;
        byte[] responseDataBytes = responeData.getBytes();
        DatagramPacket responsePacket = new DatagramPacket(responseDataBytes,
                responseDataBytes.length,receivePack.getAddress(),receivePack.getPort());
        ds.send(responsePacket);
        ds.close();
    }
}

搜索方:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPSeacher {
    public static void main(String[] args) throws IOException {
        System.out.println("UDPSeacher started");
        //搜索方负责发送数据,因此本机的发送端口可以让系统随机分配,不人为指定
        DatagramSocket ds = new DatagramSocket();


        //构建发送数据
        String requestData = "Hello world";
        byte[] requestDataBytes = requestData.getBytes();//以当前系统默认的编码转称对应的字节序。
        //直接构建packet
        DatagramPacket requestPacket = new DatagramPacket(requestDataBytes,
                requestDataBytes.length);
             //设置发送报文的信息,如本机IP,目标端口20000
        requestPacket.setAddress(InetAddress.getLocalHost());
        //往对方主机的20000端口发送数据
        requestPacket.setPort(20000);
        ds.send(requestPacket);

        //接收信息的实体
        final byte[] buf = new byte[512];
        DatagramPacket receivePack = new DatagramPacket(buf,buf.length);
        //接收
        ds.receive(receivePack);
        //发送者的IP
        String ip = receivePack.getAddress().getHostAddress();
        int port = receivePack.getPort();
        int dataLen = receivePack.getLength();
        String data = new String(receivePack.getData(),0,dataLen);
        System.out.println("UDPSeacher receive from IP:"+ip+" port:"+port
        +"\t"+"data:"+data);

        ds.close();
    }
}

先运行提供方,再运行搜索方,因为提供方是监听的,没有监听,你发信息没人能收。

效果:

提供方:

从下面结果看来,提供方收到了搜索方法来的data:hello world。并且可以知道,搜索方的端口号是61877(这是随机的分配的,但提供方监听的端口号则是人为固定的)

搜索方:

结合提供方的代码可知,提供方收到搜索方法来的数据后,是会恢复一个数据给搜索方的。从搜索方的结果看来,确实是收到了提供方的回复数据,端口是20000,没错,因为提供方的端口就是20000。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值