UDP编程

背景

进行网络编程,就需要传输层为应用层提供的api,称为socket api,其中传输层提供了两种协议,TCP和UDP,其所对应的socket api也是不同的,下面介绍的是UDP协议

1.特点

1.无连接(就像发微信、QQ一样无需对方回应,建立连接,消息也能发过去,而相对应的有连接则是像电话这样的,对方需要接电话,建立连接才能通信)
2.不可靠传输(不知道对方有无收到消息,就像微信一样,对方有没有看见自己的消息是不知道的)
3.面向数据报(以数据报为传输的基本单位)
4.全双工(支持双向通信,可以在A给B通信的同时,B给A通信)

2.核心类

UDP的socket api提供的两大核心类分别为DatagramSocket类和DatagramPacket类
1.DatagramSocket 叫作socket类,本质上是一个文件,在系统中,还有一种特殊的socket文件,对应于网卡设备,进行网络通信,就需要打开一个内核中的socket文件,可以构造DatagramSocket对象来打开这个文件
2.DatagramPacket类,表示一个UDP数据报,传输数据,就是以DatagramPacket为基本单位
3.还有一个重要的类InetSocketAddress,是用来创建Socket地址,包含IP地址和端口号。

3.回显服务器的实现

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;


public class UdpEchoServer {
    //要创建UDP服务器,需要先打开一个socket文件
    private DatagramSocket socket = null;
    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);//绑定一个端口,将进程和端口号关联起来,程序如果要进行网络通信就需要一个端口号,端口号相当于网络上区分进程的身份标识符,端口号范围是0到65535
    }
    //启动服务器
    public void start() throws IOException {
        System.out.println("服务器启动");
        while(true){
            //1.读取客户端发来的请求
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);//分配了一段长度为4096的缓冲区(内存空间)
            socket.receive(requestPacket);//若客户端没发请求,receive就会阻塞等待,直到有请求,才会读取数据并且返回到输出型参数
            //2.对请求进行解析,把DatagramPacket(本质上是字节数组)转成一个String
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());//将缓冲区中的字节数组取出来,转成字符串
           //3.根据请求处理响应
            String response = process(request);
            //4.把响应构造成DatagramPacket对象,用字符串里面的字节数组来构造内容,指定长度,还要将响应返回给客户端,getSocketAddress()是用了requestPacket存储的客户端的IP地址和端口号
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
            //5.把这个DatagramPacket对象返回给客户端
            socket.send(responsePacket);
            System.out.println("客户端IP"+requestPacket.getAddress().toString()+"端口号"+requestPacket.getPort()+"请求"+request+"响应"+response);
        }
    }
//通过这个方法,实现根据请求处理响应,根据自己的实际情况来编写代码,此处是回显服务器,发来什么返回什么。
    private String process(String request) {
        return request;
    }
//启动服务器
    public static void main(String[] args) throws IOException {
        UdpEchoServer udpEchoServer = new UdpEchoServer(6888);//端口号一般不能取1024以下的端口,是系统保留的端口,特殊端口。一般取1024到65535
        udpEchoServer.start();
    }
}

4.客户端的实现

import java.awt.*;
import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class UdpEchoClient {
    private DatagramSocket socket = null;

    public UdpEchoClient() throws SocketException {
        //服务器得有固定端口客户端才好访问,客户端程序安装在用户电脑上,用户电脑上的端口号是不可控的,若指定端口号很有可能会重复
        socket = new DatagramSocket();//客户端端口号一般是由操作系统自动分配

    }

    public  void start() throws IOException {
        Scanner scanner = new Scanner(System.in);

        while (true) {
            //1.让客户端从控制台读取一个数据
            String request = scanner.next();
            //2.把这个请求发送给服务器,构造DatagramPacket,需要包含请求的数据内容和服务器的IP地址和端口号,127.0.0.1是环回IP,表示当前主机。
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName("127.0.0.1"),6888);
            //3.把数据发送给服务器
            socket.send(requestPacket);
            //4.从服务器读取响应数据
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacket);
            //5.转换响应的数据变成字符串
            String response = new String(responsePacket.getData(),0,responsePacket.getLength());
            System.out.println("request  "+request+ "   response  "+response);
        }

    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient udpEchoClient = new UdpEchoClient();
        udpEchoClient.start();
    }
}

在这里插入图片描述
在这里插入图片描述
把这个√上就可以同时启动多个客户端。

4. close方法

上述构造了一个DatagramSocket对象,相当于打开了一个特殊文件,但没有关闭文件是因为socket对象生命周期是伴随整个进程的,而这个进程是始终没有结束的,故不能提前关闭socket对象,而当进程结束的时候,对应的PCB也就没有了,文件描述符也没有了,也就相当于关闭了文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值