UDP SocketAPI

文章介绍了TCP和UDP的主要区别,包括TCP的连接性、可靠传输和面向字节流,以及UDP的无连接、不可靠传输和面向数据报特性。接着,详细展示了如何使用Java的DatagramSocket和DatagramPacket类实现UDP的回显服务器和客户端,包括服务器接收和回应客户端请求的步骤。此外,还提到了UDP翻译服务器的概念,通过HashMap存储翻译词典,实现简单的查询功能。
摘要由CSDN通过智能技术生成

1、TCP与UDP区别

TCP:有连接,可靠传输,面向字节流,全双工

UDP:无连接,不可靠传输,面向数据报,全双工

2、UDP  sockeAPI的核心类

DatagramSocket:相当于对socket文件进行封装,有了socket文件以后,就可以真正操作网卡,发送和接收数据。

DatagramPacket:发送和接收数据的基本单位。

close方法,在下面代码中没有用到,文件打开之后要及时关闭,为啥下列代码不进行关闭呢?

 代码中的socket对象,生命周期伴随整个进程,因此进程结束前,提前关闭socket对象不合适,当进程结束时,对应的PCB也没了,PCB文件上的文件描述符表也没了,也就相当于关闭了。

3、客户端和服务器的工作流程

 

一、回显

1、服务器

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);
    }

    //启动服务器
    public void start() throws IOException {
        System.out.println("服务器启动!");
        while(true){
            //1、读取客户端发来的请求
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(requestPacket);
            //2、对请求进行解析,把datagramPacket 转成一个string
            String request = new String(requestPacket.getData(),0, requestPacket.getLength());
            //3、根据请求,处理响应,虽然咱们这个是回显服务器,但还是可以搞个单独的方法来做这个事情
            String response = process(request);
            //4、把响应构造成 DatagramPacket 对象返回给客户端
            //   构造响应对象,要搞清楚,对象要发给谁(谁给咱们发的请求,就把响应发给谁!!)
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
            //5、把这个DatagramPacket 对象返回给客户端
            socket.send(responsePacket);
            System.out.printf("[%s:%d] req=%s ; resp=%s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);
        }
    }
    //通过这个方法,实现根据请求计算响应这个过程
    //但是由于是回显服务器,所以不涉及到其他逻辑,但如果是其他服务器,就可以在 process 里面,来加上一些其他逻辑的处理
    public String process(String req){
        return req;
    }

    public static void main(String[] args) throws IOException {
        //main方法是真正启动服务器,这个端口号说是随便写,但是也是有范围的,0 - 65535
        //一般来说1024以下的端口,都是系统保留,一般不使用
        //因此咱们写代码,端口号尽量选择 1024 - 65535
        UdpEchoServer server = new UdpEchoServer(8000);
        server.start();
    }
}

2、客户端

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、让客户端从控制台读取一个请求数据
            System.out.print("> ");
            String request = scanner.next();
            //2、把这个字符串请求发送给服务器,构造 DatagramPocket
            //   构造的DatagramPocket 既要包含传输的数据 ,又要包含把数据发送到哪里
            DatagramPacket requestPocket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName("127.0.0.1"),8000);
            socket.send(requestPocket);
            //4、从服务器读取响应数据
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacket);
            //5、把响应数据获取出来,转成字符串
            String response = new String(responsePacket.getData(),0,responsePacket.getLength());
            System.out.printf("req:%s;resp:%s\n",request,response);
        }
    }

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

二、翻译服务器

在回显服务器的基础上,运用hash MAP

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;

public class UdpDictServer extends UdpEchoServer{
    private Map<String,String> dict = new HashMap<>();
    public UdpDictServer(int port) throws SocketException {
        super(port);
        dict.put("cat","小猫");
        dict.put("dog","小狗");
        dict.put("baobao","瑾瑾");

    }

    //和 UdpEchoServer 相比,只是process不同,就重写这个方法即可
    @Override
    public String process(String req) {
        return dict.getOrDefault(req,"这个词俺也不知道");
    }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值