java-ee UDP/TCP

UDP:用户数据报协议

特点:

①无连接;②不可靠传输;③面向数据报;④全双工

TCP:传输控制协议

特点:

①有连接;②可靠传输;③面向字节流;④全双工

无连接:使用UDP通信的双方,不需要刻意保存对端的基本信息,不需要接收连接也能通信

(比如使用微信发送,及时他没有登录微信,我也可以将我的内容发送给他)

有连接:使用TCP通信的双方,则需要可以保存对端的基本信息,需要先接收连接才能通信

(比如打电话,要记录对方的电话号码,当我拨打电话时,对方必须接通才能进行通话)

不可靠传输:消息发送了,但是并不关注是否发送成功

可靠传输:消息发送了,不能百分百的发送到达对方,但是尽可能的传输过去

面向数据报:以一个UDP数据报为单位

面向字节流:以字节为单位传输,读写方式灵活

全双工:一条路径,双向通信

要想进行通信,需要有socket文件这样的对象,借助socket文件对象间接操作网卡

往这个socket文件里面写数据,相当于通过网卡发送数据;往这个socket文件里面读数据,相当于通过网卡接收消息

UDP数据报套接字变成

DatagramSocket 是UDP Socket,用于发送和接受UDP数据

对象 是一个socket对象

构造方法:

①DatagramSocket():

创建一个UDP数据包套接字的Socket,绑定到本机任意一个随机端口

(无参数的一般用于客户端,客户端不需要手动指定端口号,系统会自动分配)

②DategramSocket(int port):

创建一个UDP数据包套接字的Socket,绑定到本机指定的端口

(一般用于服务端,需要手动提供端口号)

方法:

①void receive():从套接字接收数据,若没有数据,receive会阻塞等待,直到有数据为止

②void send():从套接字中发送数据报

③void close():关闭数据包套接字

DatagramPacket是UDP Socket发送和接受数据的数据报

构造方法:

①DatagramPacket(byte[] buf,int length):

构造一个DatagramPacket用来接收数据报,第一个参数是存放数据报的内容,第二个参数是这个数据包的长度

②DatagramPacket(byte[] buf,int offset.int length,SocketAddress address):

构造一个DatagramPacket用来发送数据报,第一个参数是数据报的内容,第二个参数是想要发送数据报内容的起始位置,第三个参数是想要发送的数据报长度,第四个参数是指定目的主机的端口号和ip

以UDP来实现一个简单的回显服务器

客户端发送一个请求,服务器响应一个一模一样的请求

同一个主机上,一个端口号同一时刻只能被一个进程使用

java-ee UDP/TCP_第1张图片

服务端:

public class UdpEchoSevert {
    //要进行通信,必须要有socket对象
    DatagramSocket socket = null;
    //服务端要指定端口号,所以在构造方法中,创建socket对象并且指定绑定的端口号
    public UdpEchoSevert(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }

    //服务器启动
    public void star() throws IOException {
        while(true) {
            System.out.println("服务器启动:");
            //1.读取请求并分析
            //创建一个长度为4090的数据报,目前里面还没有存放东西
            DatagramPacket requestPacket = new DatagramPacket(new byte[4090],4090);
            socket.receive(requestPacket);//将读取到的信息放入到这个数据包中
            //为了方便计算响应,将数据包转换成String类型
            //requestPacket.getData()获取到数据包的内容,从0位置开始,到这个数据包的长度
            String request = new String(requestPacket.getData(),0, requestPacket.getLength());
            //2.根据请求计算响应
            String respond = process(request);
            //计算的响应结果放到响应的数据包中,构造响应要指定将这个数据报发送给谁
            //respond.getBytes()响应结果内容的起始位置,respond.getBytes().length响应结果内容的长度
            // requestPacket.getSocketAddress()获取到ip和端口号
            DatagramPacket respondPacket = new DatagramPacket(respond.getBytes(),respond.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(respondPacket);
            System.out.printf("[%s:%d] req: %s, rest: %s\n",requestPacket.getAddress().toString(),
                    requestPacket.getPort(),request,respond);
        }
    }
    public static String process(String request) {
        return request;
    }
    public static void main(String[] args) throws IOException {
       UdpEchoSevert udpEchoSevert = new UdpEchoSevert(9090);
       udpEchoSevert.star();
    }
}

客户端:

public class UdpEchoClient {
    //进行通信要有socket对象
    private DatagramSocket socket = null;
    private String severtIp;//ip
    private int severtPort;//端口号
    //构造socket对象,并且不需要手动指定端口号,在传输时需要明确ip和端口号
    public UdpEchoClient(String severtIp,int severtPort) throws SocketException {
        //客户端不需要手动指定要进行通信的端口号
        socket = new DatagramSocket();
        this.severtIp = severtIp;
        this.severtPort = severtPort;
    }

    //
    public void star() throws IOException {
        //不断的发送请求
        Scanner scanner = new Scanner(System.in);
        while(true) {
            //1.读取用户从控制台输入的数据
            System.out.println("请输入:");
            String request = scanner.nextLine();
            //2.构造请求数据包并发送数据包
            //request.getBytes()获取用户输入的内容 request.getBytes().length内容的的长度是数据包的长度
            //构造发送数据报,要指定目的主机的ip和端口号
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(severtIp),severtPort);
            //客户端发送请求
            socket.send(requestPacket);
            //3.接受服务端的响应
            DatagramPacket respondPacket = new DatagramPacket(new byte[4090],4090);
            socket.receive(respondPacket);//receive将接受到的响应内放到respondPacket报里面
            //4.将响应内容转化成字符串,显示在控制台上
            String respond = new String(respondPacket.getData(),0,respondPacket.getLength());
            System.out.printf("req : %s , resp : %s\n",request,respond);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);
        udpEchoClient.star();
    }
}

服务端显示的结果:

java-ee UDP/TCP_第2张图片

客户端显示的结果:

java-ee UDP/TCP_第3张图片

你可能感兴趣的:(udp,tcp/ip,网络)