欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

7.3(java学习笔记)网络编程之UDP

程序员文章站 2022-04-14 10:57:09
一、UDP UDP的全称是User Datagram Protocol(用户数据报协议),是一种无连接的不安全的传输协议, 传输数据时发送方和接收方无需建立连接,所以是不安全的。 发送时不建立连接直接发送,发送后不关注接受方能否接到。UDP只负责发出去,后续的事情与之无关。 1)、使用UDP发送和接 ......

一、udp

  udp的全称是user datagram protocol(用户数据报协议),是一种无连接的不安全的传输协议,

  传输数据时发送方和接收方无需建立连接,所以是不安全的。

  发送时不建立连接直接发送,发送后不关注接受方能否接到。udp只负责发出去,后续的事情与之无关。

 

  1)、使用udp发送和接受数据的过程:

  1接收数据:

    1.1创建数据包实例,用于接收数据。(指定接收方ip,端口)

    1.2创建接收容器

    1.3将接收容器封装成包

    1.4接收包

    1.5处理包(可以看做拆包,将包中数据拿出来)

    1.6释放资源

 

  2.发送数据

    2.1创建数据报实例,用于发送数据。(指定发送ip,端口)

    2.2创建发送资源

    2.3将发送资源封装成包(包加上发送目的地,端口)

    2.4发送包

    2.5释放资源

 

  2)、datagramsocket & datagrampacket

    java中将udp封装成datagramsocket类,用于发送和接收数据报。

    2.1构造方法:

    datagramsocket(int port)//创建数据报,并绑定到本地主机的指定端口

    datagramsocket(int port, inetaddress laddr)//创建数据报,绑定到指定地址的指定端口

    2.2主要方法

    void send(datagrampacket p)//发送数据包
    void receive(datagrampacket p)//接收数据包

  

    数据需要打包后才能发送,而接收数据也是以包的形式接收,java中使用datagrampacket将数据打包。

    构造方法:

    datagrampacket(byte[] buf, int length)//构造接收数据包及其长度,(设置接收数据包)

    datagrampacket(byte[] buf, int length, inetaddress address, int port)//构造一个数据包,指定发送主机及端口信息(设置发送数据包)

    主要方法:

    int getlength()//返回要发送的或者要接受的数据长度

    byte[] getdata()//获取发生或接受的数据,相当于拆包,获取包内数据。

 

server:(接收数据) 

import java.io.ioexception;
import java.net.datagrampacket;
import java.net.datagramsocket;
import java.net.inetaddress;
import java.net.socketexception;

public class server {
    public static void main(string[] args) throws ioexception {
        datagramsocket server = new datagramsocket(8888,inetaddress.getbyname("localhost"));
        byte[] r = new byte[1024];//接收容器
        datagrampacket packet = new datagrampacket(r,r.length);//打包
        server.receive(packet);//接收包
        system.out.println(new string(packet.getdata(),0,packet.getlength()));//拆包并解析包
        server.close();        
    }
}

 

client:(发送数据)   

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 client {

    public static void main(string[] args) throws ioexception {
        // todo auto-generated method stub
        datagramsocket client = new datagramsocket(8887,inetaddress.getbyname("localhost"));
        string msg = "hello udp";
        byte[] b_msg = msg.getbytes();//数据-->字节
     //打包,并加上目的地信息 datagrampacket packet = new datagrampacket(b_msg,b_msg.length,inetaddress.getbyname("localhost"),8888); client.send(packet);//发送包 client.close();//释放资源 } }
运行结果:
hello udp

 

先运行server,server会等待数据,之后运行client发送数据,server接收到数据后就会解析。

7.3(java学习笔记)网络编程之UDP

想象成寄快递1.东西准备好(准备数据),

      2.转换为固定格式(数据转换为字节)

      3.然后打包,包上贴快递单(邮寄的目的地(ip)和接收人(端口))

      4.然后发送,

      5.接收方接收

      6.然后拆快递(拆包)

      7.然后拿到东西。(字节转换数据)

  

  

上面的数据是字符串可以直接转换为字节,但如果有时候传输的数据不能直接转换为字节这时该怎么办呢?

这就要用到io流的知识,主要使用bytearraystream(tobytearray()方法)、datastream(writexxxx()方法)。

数据-->字节:

先将数据及其格式通过dataoutputstream写入bytearrayoutputstream中,再通过bytearrayoutputstream中的tobytearray()方法将的字节拿出。

字节-->数据:

将字节数组放入bytearrayinputstream中,然后通过datainputstream中的readxxx读取bytearrayinputstream中字节数组,将其转换为对应数据类型。

server:

import java.io.bytearrayinputstream;
import java.io.datainputstream;
import java.io.ioexception;
import java.net.datagrampacket;
import java.net.datagramsocket;
import java.net.inetaddress;

public class server {
    public static void main(string[] args) throws ioexception {
        datagramsocket server = new datagramsocket(8888,inetaddress.getbyname("localhost"));
        byte[] r = new byte[1024];
        datagrampacket packet = new datagrampacket(r,r.length);
        server.receive(packet);
        system.out.println(bytetodouble(packet.getdata()));//字节转换为数组
        server.close();        
    }
    
    public static double bytetodouble(byte[] b) throws ioexception{
        bytearrayinputstream bis = new bytearrayinputstream(b);//将字节放入bytearratinputstream中
        datainputstream dis = new datainputstream(bis);//通过dis读取bis中字节
        double data = dis.readdouble();//通过dis.readxxxx读取bis中的字节数组。
        return data;
    }
}

 

client:

import java.io.bytearrayoutputstream;
import java.io.dataoutputstream;
import java.io.ioexception;
import java.net.datagrampacket;
import java.net.datagramsocket;
import java.net.inetaddress;

public class client {

    public static void main(string[] args) throws ioexception {
        // todo auto-generated method stub
        datagramsocket client = new datagramsocket(8887,inetaddress.getbyname("localhost"));
    //    string msg = "hello udp";
        double data = 9.1;
        byte[] b_data = doubletobyte(data);//数据转换为字节
        datagrampacket packet = new datagrampacket(b_data,b_data.length,inetaddress.getbyname("localhost"),8888);
        client.send(packet);
        client.close();
    }
    
    public static byte[] doubletobyte(double dou) throws ioexception{
        bytearrayoutputstream bos = new bytearrayoutputstream();//创建字节数组输入流
        dataoutputstream dos = new dataoutputstream(bos);//通过dos想bos中写入
        dos.writedouble(dou);//通过dos中的write.xxxx将dou写入bos中
        dos.flush();
        dos.close();
        byte[] data = bos.tobytearray();//将bos中字节取出。
        return data;
    }
}
运行结果:
9.1