JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

这篇具有很好参考价值的文章主要介绍了JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 禁止白嫖 T > T
  • 点点赞呗

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

1. UDP简易翻译服务器

  • 这个翻译器主要是在上一章的回显服务器和回显客户端上进行修改
  • 修改了计算响应的过程,即process方法

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

1.1 重写方法

  • 重写方法是Java中的一种重要手段
  • 指在一个类的子类里,对父类的一个方法进行重新定义!
  • 而父类的权限级别要大于等于子类~ 【除了private】
  1. 向上转型,父类对象调用的是子类重写的方法
  2. 动态绑定,子类对象调用父类的方法,但是该方法里嵌套调用了重写方法
  • 可以理解为super帮助构造父类时,实现动态绑定重写方法~
    • 而他的"super"跟子类实例化父类对象别无二致
    • 也可以看成向上转型 + 动态绑定
    • 而构造子类必然要以子类构造父类,这个过程才是重写方法的本质

子类继承父类,并为帮助父类构造:
JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

Ctrl + O 重写process方法:

  • 注意:父类的process权限要足够高才行~

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  • 注解的作用就是警示你写对代码!
    • 不至于写了半天出错了,找不到代码错误的地方~

1.2 设计翻译服务器

  • 对于这个简单的翻译器,我只需要将一个个单词和一个个含义对应好,并且保存起来,每次查询的时候就在里面找对应关系~
  • 而这也是一些翻译器的基本原理,一个单词字符串对象 + 映射对象占内存也不过1KB,100w个单词 也约等于 10亿字节,也就是1GB

快速记忆小技巧:

  1. Thousand ==> 1KB
  2. Million ==> 1MB
  3. Billion ==> 1GB

而符合这种需求的数据结构就是:哈希表

  1. 快速查询
  2. 映射关系 — Map

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  • 找不到的时候get返回null~

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

1.3 书写main方法启动服务器测试

public static void main(String[] args) throws IOException {
    UDPDictServer udpDictServer = new UDPDictServer(9090);
    udpDictServer.start();
}

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  • 测试正常,如果你要做大这个翻译器,可以多点单词~

2. TCP网络编程示例

  • 这个示例跟UDP的作用是一模一样的~
  • 只不过这次用到的协议是TCP

如果没有学UDP建议先学UDP!

传送门:JavaEE & 网络编程示例1 & UDP套接字数据报编程 == 一发一收

2.1 ServerSocket 与 Socket

  1. ServerSocket : 服务器使用的socket对象
  2. Socket : 既会给客户端使用,也会给服务器使用的socket对象
2.1.1 ServerSocket的构造方法
方法名 方法说明
ServerSocket(int port) 服务器socket对象构造方法【指定端口号】
  • 服务器一定要绑定具体的端口号~
2.1.2 ServerSocket的核心方法
方法名 方法说明
Socket accept() 建立连接
void close() 关闭socket【文件】对象
  • socket对象如果周期很长,一般是不需要关闭的,因为关闭时一般意味着程序终结,资源自动回收

  • accept方法是跟客户端建立连接的方法,后面写代码时重点说明

    • TCP有连接的特点就在这~
    • 连接一旦建立,发送与接受都是能确定是否成功的~
  • 返回的Socket对象,即可以代表服务器与客户端的连接,也可以代表客户端与服务器的连接~

2.1.3 Socket的构造方法
方法名 方法说明
Socket(String host, int port) 指定IP与端口号
2.1.4 Socket的核心方法
方法名 方法说明
InetAddress getInetAddress() 返回Socket对象的IP地址
InputStreamgetInputStream() 返回控制这个socket文件的输入流
OutputStreamgetOutputStream() 返回控制这个socket文件的输出流
  • 输入输出流特别重要
    • 作用于他们就相当于作用于网卡
    • 有了他们,我们就可以进行数据的沟通了!

而他们对应的是字节流 ==> TCP面向字节流

2.1.5 长连接与短连接
  1. 服务器收到一个请求,就返回一个响应,然后断开连接

这就是短连接

  1. 服务器收到一个客户端的多条请求,再一起返回响应,然后断开连接

这就是长连接

  • 而长短连接都是可能出现的!

对于接下来的代码,考虑到多条请求,我做出如下规定:

  • 多条请求之间以空白符分割~
  • 每一个请求都是字符串

对于后面的代码设计,是按长连接来设计的!

2.2 基于TCP 的 Socket 写一个简单的客户端服务器程序

同样的,分为服务器与客户端:

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  • 同样也可以做成翻译器~
2.2.1 TCP回显服务器
  • 可能在前面会很懵,但是后面的图解会串联起来,可能会让你理解起来更加容易!
2.2.1.1 ServerScoket对象与构造方法
  • 这个对象是专门给服务器用的,通过这个对象来获得客户端【发来请求的机器】的【socket管理员】
    • 即连接
  • 而这个socket并不是用于操纵socket文件~
public class TCPEchoServer {
    private ServerSocket serverSocket = null;

    public TCPEchoServer(int port) throws IOException {
        this.serverSocket = new ServerSocket(port);
    }
}
2.2.1.2 start启动方法
  • Socket对象被动构造
  • accept的话,则是接受客户端的输出
public void start() throws IOException {
    System.out.println("服务器启动!");
    while(true) {
        Socket clientSocket = serverSocket.accept();//建立连接
        processConnect(clientSocket); // 连接成功后进行一些操作~
   }
}

你可能有一个疑惑:

  • 发送信息要用到客户端socket对象这没问题
  • 但是,接受到的信息为什么也用到客户端的socket对象?
  1. 服务器收到的信息可能来自很多地方,并且都是字节流,不像数据报一块一块的
  2. 服务器的输出流数据来源来自客户端的输入流
    • 输入:我输入给别人
    • 输出:别人输出给我

如以下关系:

  • socket文件内有两块缓冲区
    1. 接受缓冲区
    2. 发送缓冲区

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  • 即,只需要知道一方,就可以完成读写~
  • 而那一方应该是“对方”
2.2.1.3 processConnect细节
public void processConnect(Socket clientSocket) throws IOException {
    System.out.printf("[%s:%d] 客户端上线\n", clientSocket.getInetAddress().toString(),
            clientSocket.getPort());
    try(InputStream inputStream = clientSocket.getInputStream();
        OutputStream outputStream = clientSocket.getOutputStream()) {
        Scanner scanner = new Scanner(inputStream);
        //这个对象将自动读取【字节流/其他流】为【字符流】
        PrintWriter printWriter = new PrintWriter(outputStream);
        //这个对象将自动写入【字符流】化为【字节流/其他流】
        while(scanner.hasNext()) {//死循环了,除非客户端关闭~
            String request = scanner.next();//nextLine有坑很烦
            String response = process(request);
            printWriter.println(response);//换行记得加~
            printWriter.flush();
            System.out.printf("[%s : %d] 发来请求:%s, 将对其返回响应:%s\n", clientSocket.getInetAddress().toString(),
                    clientSocket.getPort(), request, response);
        }
        System.out.printf("[%s:%d] 客户端下线\n", clientSocket.getInetAddress().toString(),
                clientSocket.getPort());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        clientSocket.close();
    }
}

讲解:

  • 抛异常操作自己去抛
  1. 客户端上线打印日志

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  1. 打开输入输出流

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  1. 字节流转换器
    • 通过这两个对象,实现传输过程

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  • 如何理解输入与输出流?

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  1. 建立长连接

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  1. 获得请求并计算

    • 回显计算:

    • public String process(String request) {
          return request;
      }
      
    • 这里的flush特别重要,当你flush后,才能算真正输出了~

      • 即,对方就能接受你的输出,并且用你的输入流去获得~
      • scanner在等待输入呢,flush就相当于踢了它一脚~
    • 打印日志~

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

2.2.2 TCP回显客户端
2.2.2.1 指定服务器Socket对象与构造方法
  • 会用这个对象就行了,至于这么通过端口获得对应的输入输出流的不得而知~
public class TCPEchoClient {
    Socket socket = null;//此socket对象代表了服务器的socket文件~

    public TCPEchoClient(String host, int port) throws IOException {
        this.socket = new Socket(host, port);
        //这个过程客户端主动连接了服务器,这样就可以被服务器的accept接受~
        //而服务器的accept返回的对象,默认填上了客户端的IP与端口号
    }
}

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

2.2.2.2 start启动方法
public void start() {
    Scanner scanner = new Scanner(System.in);
    try (InputStream inputStream = socket.getInputStream();
         OutputStream outputStream = socket.getOutputStream()){
        PrintWriter printWriter = new PrintWriter(outputStream);
        Scanner scannerFromServer = new Scanner(inputStream);
        while(true) {
            System.out.print("-> ");
            String request = scanner.nextLine();
            printWriter.println(request);
            printWriter.flush();
            String response = scannerFromServer.next();//如果为空,则需要等待对方flush
            System.out.printf("[%s : %d] 收到请求:%s, 返回响应:%s\n", socket.getInetAddress().toString(),
                    socket.getPort(), request, response);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

讲解:

  1. 获得服务器的输入输出流

    • 同样的方式~
      JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端
  2. 字节流转换器
    JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  3. 多次请求响应

    • “写”的时候,记得带上“回车空白符”,分割每个响应
      • 并打印日志

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

可能会更加难理解,但是也简化了UDP反复制作“数据报”的过程,并且是有连接的~

2.2.2.3 补充说明

长连接是指一个服务器一段时间内反复服务一个客户端

  • 客户端socket这段时间内一直处于打开状态,并不断发送请求得到响应~

并不是一次性发送多条请求,得到多条响应~

  • 错误代码:
    • 这段代码确实可以完成一次上面的流程
    • 但是有不可修复的bug!

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

2.2.3 测试与总结
  • 服务器进程:
    • 端口号随便写的(空余的)
public static void main(String[] args) throws IOException {
    TCPEchoServer tcpEchoServer = new TCPEchoServer(9090);
    tcpEchoServer.start();
}
  • 客户端进程:
    • IP自己去查~
public static void main(String[] args) throws IOException {
    TCPEchoClient tcpEchoClient = new TCPEchoClient("10.61.10.239", 9090);
    tcpEchoClient.start();
}

运行测试(“死锁”版):

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

运行测试(正常版):

  • 对于一次性输入多条请求,获得多个响应也只能这样~

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

总结图示:

  • 下一次控制台输入,又是一次轮回~

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

2.2.4 修复缺陷

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  • 运行两个客户端:

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

你可能已经发现了,这个代码还存在一个缺陷

  • 就是这个服务器,在一段时间内,“抢到服务器”的客户端不关闭,服务器就无法服务其他客户端。
  • 那怎么办!

其实,很简单

  • 线程池 / 循环建立多线程
  • 只要让服务器并发的去执行任务就ok了!

但是,客户端达到一定数量会导致系统崩了或者客户端未能“同时”受到服务

  • 即,肉眼可见的不并发

代码改进:

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

  • 运行结果:

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端

线程池法:

JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端


文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆

后续网络编程的博客会陆续更新,敬请期待!文章来源地址https://www.toymoban.com/news/detail-415719.html


到了这里,关于JavaEE & UDP简易翻译服务器 & 网络编程示例2 & TCP回显服务器,回显客户端的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【网络编程】demo版UDP网络服务器实现

    在上一章【网络编程】socket套接字中我们讲述了TCP/UDP协议,这一篇就是简单实现一个UDP协议的网络服务器。 我们也讲过其实 网络通信的本质就是进程间通信 。而进程间通信无非就是读和写(IO)。 所以现在我们就要写一个服务端(server)接收数据,客户端(client)发送数据

    2024年02月02日
    浏览(47)
  • unix网络编程-简易服务器与客户端程序解析

    a -- address f -- file        eg: fputs() -- file put stream fd -- file descriptor h - host(主机) in/inet -- internet        eg: sockaddr_in; inet_aton n -- network(网络字节序)/numeric(数值) p -- protocol(协议)/presentation(表达/呈现形式) s -- socket        eg: sin -- socket internet t -- type,用于指定某种

    2024年01月16日
    浏览(69)
  • 【网络编程】实现UDP/TCP客户端、服务器

    需要云服务器等云产品来学习Linux的同学可以移步/--腾讯云--/--阿里云--/--华为云--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。   目录 一、UDP 1、Linux客户端、服务器 1.1udpServer.hpp 1.2udpServer.cc 1.3udpClient.hpp 1.4udpClient.cc 1.5onlineUser.hpp 2、Windows客户端 二、T

    2024年02月06日
    浏览(61)
  • 网络编程套接字(二)之UDP服务器简单实现

    目录 一、服务端UdpServer 1、udp_server.hpp 1、服务器的初始化 2、服务器的运行 2、udp_server.cc 二、客户端UdpClient udp_client.cc 三、完整代码 首先,我们在该文件中,将服务器封装成一个类,而作为一款服务器,必须要有自己的端口号,同时网络服务器需要有对应的IP地址,文件描述

    2024年04月16日
    浏览(57)
  • Linux网络编程:线程池并发服务器 _UDP客户端和服务器_本地和网络套接字

    文章目录: 一:线程池模块分析 threadpool.c 二:UDP通信 1.TCP通信和UDP通信各自的优缺点 2.UDP实现的C/S模型 server.c client.c 三:套接字  1.本地套接字 2.本地套 和 网络套对比 server.c client.c threadpool.c   server.c client.c server.c client.c

    2024年02月11日
    浏览(66)
  • 【网络编程】网络套接字&udp通用服务器和客户端

    端口号(port)是传输层协议的内容: 端口号是一个2字节16位的整数(uint16) 端口号用来标识主机上的一个进程 IP地址+port能够标识网络上的某一台主机和某一个进程 一个端口号只能被一个进程占用 此处我们先对TCP(Transmission Control Protocol 传输控制协议) 有一个直观的认识,后面再

    2024年02月16日
    浏览(214)
  • 【计算机网络】网络编程套接字&UDP服务器客户端的简单模拟

    需要云服务器等云产品来学习Linux的同学可以移步/–腾讯云–/官网,轻量型云服务器低至112元/年,优惠多多。(联系我有折扣哦) 每台主机都有自己的IP地址,当数据在进行通信的时候,除了要发送的数据外,在报头里面还要包含发送方的IP和接收方的IP,这里发送方的IP就

    2024年02月20日
    浏览(64)
  • 【网络编程】基于UDP数据报实现回显服务器/客户端程序

    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程的一点学习心得,欢迎大家在评论区交流讨论💌 前言 我们如果想让应用程序进行网络通信的话,就需要调用传

    2024年02月04日
    浏览(54)
  • UDP数据报网络编程(实现简单的回显服务器,客户端)

           回显服务器表示客户端发的是啥,服务器就返回啥,主要是为了熟悉UDP数据报网络编程的基本步骤         对于程序的所有分析都写到了代码上 当我们用idea实现了上面的代码后可以通过idea如何开启多个客户端(一个代码开启多个客户端运行)来检验多个客户端向

    2024年02月13日
    浏览(62)
  • 《TCP/IP网络编程》阅读笔记--基于UDP的服务器端/客户端

    目录 1--TCP和UDP的主要区别 2--基于 UDP 的数据 I/O 函数 3--基于 UDP 的回声服务器端/客户端 4--UDP客户端Socket的地址分配 5--UDP存在数据边界 6--UDP已连接与未连接的设置 ① TCP 提供的是可靠数据传输服务,而 UDP 提供的是不可靠数据传输服务; ② UDP 在结构上比 TCP 更简洁,其不会

    2024年02月09日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包