• 基于udp实现回显服务器,翻译服务器


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


    udp socket 要掌握的类:

    1.DatagramSocket

    是UDP Socket,用于发送和接收UDP数据报。(网卡的代言人)

    构造方法:

     第一种一般用于客户端,第二种一般用于服务器

    其他方法:

     总结:socket本质上也是文件

    socket对应到网卡这个硬件设备,操作系统也是把网卡当做文件来管理的

    通过网卡发送数据写文件

    通过网卡接受数据读文件

    文件操作要先打开文件,然后读文件,最后关闭对应到socket上,构造方法相当于打开,receive,send相当于写,close相当于关闭

    2.DatagramPacket

    代表一个udp数据报,也就是一次发送接受的基本单位

    构造方法

    其他方法:

    一、udp版本回显服务器

    服务端:

    1.绑定端口:

    一个端口只能绑定一个进程

    2.启动服务器:

     3.接受命令:

    4.处理响应:

    5..响应写会客户端
     

    InetSocketAddress(getAddress(), getPort());

     6.打印日志

    完整代码

    1. package net_1011;
    2. import java.io.IOException;
    3. import java.net.DatagramPacket;
    4. import java.net.DatagramSocket;
    5. import java.net.SocketException;
    6. import java.nio.charset.StandardCharsets;
    7. public class UdpEchnoServer {
    8. private DatagramSocket socket=null;
    9. //参数的端口表示咱的服务器要绑定的端口
    10. public UdpEchnoServer(int port) throws SocketException {
    11. socket=new DatagramSocket(port);
    12. }
    13. //通过这个方法启动服务器
    14. public void start()throws IOException{
    15. System.out.println("服务器启动!");
    16. while(true){
    17. //循环里面处理一次请求
    18. //读取请求并解析
    19. DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);
    20. socket.receive(requestPacket);
    21. //把这个DatagramPacket对象转变成字符串,方便去打印
    22. String request=new String(requestPacket.getData(),0,requestPacket.getLength());
    23. //2.根据请求计算相应
    24. String response =process(request);
    25. //3.把相应写回到客户端
    26. DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,
    27. requestPacket.getSocketAddress());
    28. socket.send(requestPacket);
    29. //4.打印一个日志,记录当前的情况
    30. System.out.printf("[%s:%d] req: %s; resp :%s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);
    31. }
    32. }
    33. //当前写的是一个回显服务器
    34. //相应数据和请求数据是一样的
    35. public String process(String request) {
    36. return request;
    37. }
    38. public static void main(String[] args) throws IOException {
    39. UdpEchnoServer server=new UdpEchnoServer(9090);
    40. server.start();
    41. }
    42. }

    客户端:

    1.绑定端口(注意区别)Ip+端口

     服务器的ip一般都是本机ip不需要绑定,当涉及多个网卡,多个Ip,访问指定ip地址,服务器才要手动指定ip

    2.注意构造方法没有指定参数

    //这里并不是说没有端口,而是让系统自动指定一个空闲的端口

    系统分配的空闲端口,避免用户乱输入端口,导致影响到进程运行中的端口,

    3.注意构造出的数据报是以字节为单位

     4.关于DatagramPacket构造的几种方式:

    完整代码

    1. package net_1011;
    2. import java.io.IOException;
    3. import java.net.DatagramPacket;
    4. import java.net.SocketException;
    5. import java.net.*;
    6. import java.util.Scanner;
    7. public class UdpEchoClient {
    8. private DatagramSocket socket=null;
    9. private String serverIP;
    10. private int serverPort;
    11. //俩个参数一会会在发送数据的时候用到
    12. //暂时先把这俩参数存起来,以备后用
    13. public UdpEchoClient(String serverIP,int serverPort) throws SocketException {
    14. //这里并不是说没有端口,而是让系统自动指定一个空闲的端口
    15. socket=new DatagramSocket();
    16. //假设 serverIP 是形如 1.2.3.4 这种点分十进制的表示方式
    17. this.serverIP=serverIP;
    18. this.serverPort=serverPort;
    19. }
    20. public void start() throws IOException {
    21. Scanner scanner=new Scanner(System.in);
    22. while(true){
    23. //1.从控制台读取用户输入的内容
    24. System.out.println("-> ");
    25. String request=scanner.next();
    26. //2.构造一个udp请求,发送给服务器
    27. DatagramPacket requstPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,
    28. InetAddress.getByName(this.serverIP),this.serverPort);
    29. socket.send(requstPacket);
    30. //3.从服务器中读取udp响应数据,并解析
    31. DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);
    32. socket.receive(requstPacket);
    33. String response=new String(responsePacket.getData(),0,responsePacket.getLength());
    34. //4.把服务器的响应显示到控制台上
    35. System.out.println(response);
    36. }
    37. }
    38. public static void main(String[] args) throws IOException {
    39. UdpEchoClient client=new UdpEchoClient("127.0.0.1",9090);
    40. client.start();
    41. }
    42. }

     总的执行流程:

    直观表示:

     怎样处理多个请求:

    对于服务器来说

    读取请求并接续,根据请求并计算相应,把响应写会到客户端执行速度极快,这时候如果有多个客户端发来请求,服务器也是可以响应的在服务器上本质是三个请求串行处理的

    如果处理不过来,采用分布式

    udp版本翻译服务器:

     代码:

    1. package net_1011;
    2. import java.io.IOException;
    3. import java.net.SocketException;
    4. import java.util.HashMap;
    5. import java.util.Map;
    6. public class UdpTranslateServer extends UdpEchnoServer{
    7. //翻译是啥?本质上就是 key ->value
    8. private Mapdict=new HashMap<>();
    9. public UdpTranslateServer(int port) throws SocketException {
    10. super(port);
    11. dict.put("cat","小猫");
    12. dict.put("dog","小狗");
    13. dict.put("fuck","卧槽");
    14. //在这里就可以填入很多很多内容,像有道词典程序就这样
    15. }
    16. //重写process 方法,实现查询哈希表的操作
    17. @Override
    18. public String process(String request){
    19. return dict.getOrDefault(request,"词在词典中未找到");
    20. }
    21. //start方法和父类完全一样,不用写了
    22. public static void main(String[]args) throws IOException{
    23. UdpTranslateServer server=new UdpTranslateServer(9090);
    24. server.start();
    25. }
    26. }

  • 相关阅读:
    2019年亚太杯APMCM数学建模大赛B题区域经济活力及其影响因素的分析与决策求解全过程文档及程序
    shopyy建站的功能
    正则表达式在java里的运用
    2024级199管理类联考之写作
    算法之排序
    MongoDB的聚合笔记
    DeFi分析师:如何构建加密货币分析研究框架?
    14.1 Socket 套接字编程入门
    数据结构与算法之LeetCode-662. 二叉树最大宽度 -(DFS,BFS)
    动视密码重置一直提示密码不足8位
  • 原文地址:https://blog.csdn.net/panpanaa/article/details/127719698