UDP套接字的使用

Java中UDP套接字的应用

        Java中使⽤UDP协议通信,主要基于 DatagramSocket 类来创建数据报套接字,并使⽤
DatagramPacket 作为发送或接收的UDP数据报.

        DatagramSocket

        DatagramSocket 是UDP Socket,⽤于发送和接收UDP数据报.主要方法如下:

方法签名说明
DatagramSocket()创建一个UDP数据报套接字的Socket,绑定一个随机的端口(一般用于客户端).
DatagramSocket(int port)创建一个UDP数据报套接字的Socket,绑定一个指定的端口(一般用于服务端).
void receive(DatagramPacket p)从此套接字接收数据报,将接收到的数据报传给p使用,如果没有数据报则等待数据报的到来.
void send(DatagramPacket  p)从此套接字发送数据报.
void close()关闭此数据报套接字

        DatagramPacket

        DatagramPacket是UDP Socket发送和接收的数据报.主要方法如下:

方法签名方法说明
DatagramPacket(byte[] buf,int length)创建一个DatagramPacket用于接收数据报,接收的数据存储在byte数组中,接收指定长度length.
DatagramPacket(byte[] buf,int offset,int length,SocketAddress address)创建一个DatagramPacket用于接收数据报,接收的数据存储在byte数组中,接收从offset到指定长度length,address指定目标的ip和端口.
InetAddress getAddress()从数据报中获得IP地址
int getPort()从数据报中获得端口号
SocketAddress getSocketAddress()从数据报中获取IP和端口号
byte[] getData()从数据报中获得数据
int getLength()获取数据的有效长度

        构造UDP发送的数据报时,需要传⼊SocketAddress,该对象可以使⽤,InetSocketAddress来创建.InetSocketAddress(InetAddress ip,int port),创建一个Socket地址,包含ip和端口号.

        建立一个简单的回显服务器

        Server

        服务端负责接收客户端发送来的数据版,然后处理相应逻辑,返回给客户端一个响应.

public class Server {
    private DatagramSocket socket = null;

    public Server(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }

    public void start() throws IOException {
        //不断扫描获取请求
        while(true){
            //创建请求数据报对象
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            //接收数据报
            socket.receive(requestPacket);
            //将数据报内容转换为String方便计算逻辑
            String request = new String(requestPacket.getData(),0, requestPacket.getLength());
            //计算响应
            String response = process(request);
            //将响应打包为数据报 返回给客户端 客户端IP和端口从请求报文中获取
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);

            //打印服务器日志
            System.out.printf("[%s:%d] req: %s,resp: %s",requestPacket.getAddress(),requestPacket.getPort(),
                    request,response);
        }
    }

    private String process(String request) {
        return "响应: "+request;
    }

    public static void main(String[] args) throws IOException {
        Server server = new Server(8848);
        server.start();
    }
}

        Client

        客户端负责向服务端发送请求,并等待接收服务端的响应. 与服务端不同的是,客户端不能指定端口,因为无法知晓客户端的端口占用情况,而服务端在开发者手中,可以预先知晓服务端的端口占用情况,因此服务端可以指定端口号,而客户端不能指定端口号.

public class Client {
    private DatagramSocket socket = null;
    //客户端存储服务端Ip以及端口
    private String serverIP;
    private int serverPort;

    public Client(String IP,int port) throws SocketException {
        this.serverIP = IP;
        this.serverPort = port;
        //客户端socket不需要指定端口 因为无法知晓客户端端口的占用情况
        socket = new DatagramSocket();
    }

    public void start() throws IOException {
        Scanner in = new Scanner(System.in);
        while(true){
            System.out.print("->");
            if(!in.hasNext()){
                //用户不再输入时,跳出循环
                break;
            }
            //接收用户请求 并转换为请求数据报
            String request = in.next();
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
                    new InetSocketAddress(serverIP,serverPort));
            socket.send(requestPacket);
            //发送完毕后等待服务端的响应
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacket);
            String response = new String(responsePacket.getData(),0,responsePacket.getLength());
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        Client client = new Client("127.0.0.1",8848);
        client.start();
    }
}

        运行结果:

        启动客户端与服务端,从客户端发送请求,查看客户端与服务端的表现.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值