[JavaEE] 网络编程----UDP / TCP 回显服务器

Author:MTingle
major:人工智能

---------------------------------------

Build your hopes like a tower!

文章目录

文章目录

一.客户端VS服务器

二.TCP / UDP 特点

三.UDP 回显服务器

UDP 服务器

UDP 客户端

UDP字典

四.TCP 回显服务器

TCP 服务器

TCP 客户端




一.客户端VS服务器

在网络中,主动发起通信的一方称为"客户端",被动接受的这一方,称为"服务器".同一个程序在不同场景中,可以是客户端,也可能是服务器.客户端给服务器发送的数据,称为"请求"(request),服务器给客户端返回的数据,称为"响应"(response);

客户端与服务器之间的交互有多种模式.

1.一问一答:一个请求对应一个响应.最常见,例如在"web开发"中.

2.一问多答:一个请求对应多个相应.这个场景最要涉及到"下载".

3.多问一答:多个请求对应一个响应.这个场景主要涉及到"上传".

4.多问多答:一个请求可能对应多个响应,一个响应也可能对应多个请求,主要涉及到"远程控制/远程桌面"

二.TCP / UDP 特点

TCP 的特点是:有连接 可靠传输 面向字节流 全双工

UDP 的特点是:无连接 不可靠传输 面向数据报 全双工

有连接 / 无连接: 此处的连接不是物理意义上的连接,而是抽象,虚拟的连接,举个简单的例子,当我们打电话时,一边拨号,一边接通,此时才能通话,如果一方不接通,就无法进行通话,这就叫做有连接,连接首先的特点是双方都能认同.无连接类似发短信,无论你是否同意,我都能给你将信息发过去.计算机中的"网络连接"即是通信双方,各自保存对方的信息,客户端中,有一些数据结构记录了谁是他的服务器,服务器中也有一些数据结构,记录了谁是他的客户端~~

可靠传输 / 不可靠传输: 网络上"异常情况"很多,无论使用什么样的软硬件的技术手段,都无法保证网络数据100%从A运送到B.此处我们的"可靠传输"指的是尽可能的完成数据传输,虽然无法保证数据到达对方,但至少可以知道这个数据对方是否收到了,此处的可靠传输,主要指的是发送的数据没收到,发送方能否清楚地感知到.

面向字节流 / 面向数据报: 此处的字节流和文件中的字节流完全一致,网络中传输的数据的基本单位是字节.面向数据报,每次传输的单位就是一个数据报(特定的结构,数据报由一系列的字节构成).

全双工 / 半双工: 一个信息渠道可以双向通信称为全双工,只能单向通信成为半双工.

三.UDP 回显服务器

核心的类有两个:

1.DatagramSocket: 负责对 socket 文件读写,也就是借助网卡发送数据

2.DatagramPacket: 面向数据报,每次发送接收数据的基本单位,就是一个UDP数据报

UDP 服务器

public class UdpEchoServer {DatagramSocket socket=null;// 第一步: 创建DatagramSocket对象,而后的操作针对socket对象完成public UdpEchoServer(int port) throws IOException {socket=new DatagramSocket(port);}public void start() throws IOException {System.out.println("服务器启动!");while (true) {  // 对于服务器,需要不断接受请求,返回响应,于是需要用一个 while 循环// 1.接受请求并解析,byte可以保存收到的消息正文DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);String request=new String(requestPacket.getData(),0,requestPacket.getLength());// 2.根据请求响应计算String response=process(request);DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());// 3.返回响应socket.send(responsePacket);System.out.printf("[%s:%d] req:%s, resp:%s\n",responsePacket.getAddress(),responsePacket.getPort(),request,response);}}public String process(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoServer udpEcohoServer=new UdpEchoServer(9090);udpEcohoServer.start();}}

UDP 客户端

public class UdpEchoClient {private  DatagramSocket socket=null;private String serverIp;private int serverPort;public UdpEchoClient(String serverIp, int serverPort) throws SocketException {this.serverIp=serverIp;this.serverPort=serverPort;socket=new DatagramSocket();}public void start() throws IOException {System.out.println("客户端启动!");Scanner scanner=new Scanner(System.in);while (true) {System.out.printf("-> ");// 1.从控制台读取流程if (!scanner.hasNext()) {break;}String request=scanner.next();// 2.构造请求并发送DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIp),serverPort);socket.send(requestPacket);// 3.读取服务器响应DatagramPacket responsePacker=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacker);// 4.把响应显示在控制台上String response=new String(responsePacker.getData(),0,responsePacker.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient client=new UdpEchoClient("127.0.0.1",9090);client.start();}}

UDP字典

public class UdpDictServer extends UdpEchoServer {private HashMap<String,String> hashMap=new HashMap<>();public UdpDictServer(int port) throws IOException {super(port);hashMap.put("小鸡","chicken");hashMap.put("小猫","cat");hashMap.put("小狗","dog");}@Overridepublic String process(String request) {return hashMap.getOrDefault(request,"该词典中没有这个单词");}public static void main(String[] args) throws IOException {UdpDictServer udpDictServer=new UdpDictServer(9090);udpDictServer.start();}
}

四.TCP 回显服务器

TCP 服务器

public class TcpEchoServer {private ServerSocket serverSocket=null;public TcpEchoServer(int port) throws IOException {serverSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("服务端启动!\n");while (true) {// 通过accept"接听电话"后才能进行通信Socket clientSocket=serverSocket.accept();Thread t=new Thread(()->{  // 引入多线程,可以同时服务多个服务器processConnection(clientSocket);});t.start();}}private void processConnection(Socket clientSocket) {System.out.printf("[%s:%d] 客户端上线!\n",clientSocket.getInetAddress(),clientSocket.getPort());// 循环读取客户请求并反映try (InputStream inputStream= clientSocket.getInputStream();OutputStream outputStream=clientSocket.getOutputStream()){while (true) {// 通过inputStream读取数据Scanner scanner=new Scanner(inputStream);if (!scanner.hasNext()) {System.out.printf("[%s:%d] 客户端下线!\n",clientSocket.getInetAddress(),clientSocket.getPort());break;}// 1.读取请求并解析,这里有隐藏约定,next读的时候要以 空格 或 换行符 结束;String request=scanner.next();// 2.响应请求并计算String response=process(request);// 3.把响应返回给客户端//通过这种方式可以写回,但是这种方式不方便给返回的响应中添加\n// outputStream.write(response.getBytes(),0,response.getBytes().length);// 也可以给 outputstream 套上一层,完成更方便的写入。PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();System.out.printf("[%s:%d] req:%s, resp:%s\n",clientSocket.getInetAddress(),clientSocket.getPort(),request,response);}} catch (IOException e) {throw new RuntimeException(e);}}private String process(String request) {return  request;}public static void main(String[] args) throws IOException {TcpEchoServer tcpEcohoServer=new TcpEchoServer(9090);tcpEcohoServer.start();}
}

TCP 客户端

public class TcpEchoClient {private Socket socket=null;public TcpEchoClient(String serverIP, int serverPort) throws IOException {socket=new Socket(serverIP,serverPort);}public void start() throws IOException {System.out.println("客户端上线!\n");// 1.从控制台读取输入的字符串try (InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){Scanner scannerConsole=new Scanner(System.in);Scanner scannerNetwork=new Scanner(inputStream);PrintWriter writer=new PrintWriter(outputStream);while (true) {System.out.print("-> ");if (!scannerConsole.hasNext()) {break;}String request=scannerConsole.next();// 2.把请求发送给服务器,这里需要有 println 来发送,为了让发送结尾带 \n// 这里是和 scanner.next() 呼应writer.println(request);// 主动刷新缓冲器,确保数据发送writer.flush();// 3.从服务器读取响应String response=scannerNetwork.next();// 4.把响应显示出来System.out.println(response);}}finally {socket.close();}}public static void main(String[] args) throws IOException {TcpEchoClient client=new TcpEchoClient("127.0.0.1",9090);client.start();}}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/54576.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

下载分享抖音视频并转成文本

思路 将分享的链接转义成可以正常链接。通过链接去找到对应的视频链接。在通过返回的html。解析里面视频的资源链接在playAddr字段里面。拿到链接后转义urlPath即可获取到资源信息。下载视频。科大讯飞语音转文本。处理json保存到本地。 部分代码 获取抖音链接&#xff1a; …

Vue点击按钮生成pdf文件/Vue点击按钮生成png图片

本次案例是vue的点击生成pdf文件和png格式的图片 一、生成pdf文件案例 看代码之前&#xff0c;我们肯定得需要看看&#xff0c;效果图是什么的啦&#xff0c;这样子才能先看看自己想要实现的效果是不是这样子的&#xff01;上效果图嘿嘿嘿~ A、实现的效果图 这是页面&#…

java intellij idea开发步骤,使用指南,工程创建与背景色字体配置,快捷键

intellij idea2021 配置背景色&#xff0c;字体大小&#xff0c;主题 快捷键

茴香豆的茴的写法-SpringBoot处理客户端请求的几种方式

方式1&#xff1a;Controller或者RestController /*** 方式1&#xff1a;Controller* */ RestController public class AtController {GetMapping("/at")public String at() {return "Controller";} }方式2&#xff1a;Component Controller接口 /*** 方…

JACM23 - A New Algorithm for Euclidean Shortest Paths in the Plane

前言 如果你对这篇文章感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 本文关注的问题为计算几何学中的经典问题&#xff0c;即「在平面上给定一组两两不相交的多边形障碍物&#xff0c;寻找两点…

PyAutoGUI was unable to import pyscreeze.问题

转载&#xff1a; 【问题解决】 PyAutoGUI was unable to import pyscreeze.-CSDN博客 重点&#xff1a; 1.先安装pyscreeze。 2.安装pillow。

linux设置常见开机自启动命令

本文介绍了三种开机自启的方式&#xff0c;重点介绍使用systemctl的方式自启动的 方式一、修改 /etc/rc.d/rc.local 文件 /etc/rc.d/rc.local 文件会在 Linux 系统各项服务都启动完毕之后再被运行。所以你想要自己的脚本在开机后被运行的话&#xff0c;可以将自己脚本路径加到…

leetcode 380.O(1) 时间插入、删除和获取随机元素

实现RandomizedSet 类&#xff1a; RandomizedSet() 初始化 RandomizedSet 对象bool insert(int val) 当元素 val 不存在时&#xff0c;向集合中插入该项&#xff0c;并返回 true &#xff1b;否则&#xff0c;返回 false 。bool remove(int val) 当元素 val 存在时&#xff0…

C++——关联式容器(4):set和map

在接触了诸如二叉搜索树、AVL树、红黑树的树形结构之后&#xff0c;我们对树的结构有了大致的了解&#xff0c;现在引入真正的关联式容器。 首先&#xff0c;先明确了关联式容器的概念。我们之前所接触到的如vector、list等容器&#xff0c;我们知道他们实际上都是线性的数据结…

51单片机——矩阵键盘

一、矩阵键盘原理图 我们发现: P17,P16,P15,P14控制行&#xff0c; P13,P12,P11,P10控制列。 所以我们如果要选择第四列&#xff0c;只需要把整个P1先给高电位1&#xff0c;再把P10给低电位0。 二、代码 P10xFF; P100; if(P170){Delay(20);while(P170);Delay(20);KeyNum…

使用 Flask-Limiter 和 Nginx 实现接口访问次数限制

在现代 Web 应用中&#xff0c;针对敏感接口&#xff08;如短信验证码、登录接口等&#xff09;的访问次数限制至关重要。通过设置合理的限流策略&#xff0c;可以有效防止接口滥用&#xff0c;避免过多的资源消耗&#xff0c;并提升安全性。本文将通过 Nginx 和 Flask-Limiter…

axios相关知识点

一、基本概念 1、基于Promise:Axios通过Promise实现异步请求&#xff0c;避免了传统回调函数导致的“回调地狱”问题&#xff0c;使得代码更加清晰和易于维护。 2、跨平台&#xff1a;Axios既可以在浏览器中运行&#xff0c;也可以在Node.js环境中使用&#xff0c;为前后端开…

【Linux笔记】虚拟机内Linux内容复制到宿主机的Window文件夹(文件)中

一、共享文件夹 I、Windows宿主机上创建一个文件夹 目录&#xff1a;D:\Centos_iso\shared_files II、在VMware中设置共享文件夹 1、打开VMware Workstation 2、选择需要设置的Linux虚拟机&#xff0c;点击“编辑虚拟机设置”。 3、在“选项”标签页中&#xff0c;选择“共…

Can‘t connect to local MySQL server through socket

mysql -uroot ERROR 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock (2)这是mysql登录时找不到套接字的问题。 首先需要明白的是&#xff0c;Linux端的mysql server启动时会开启一个socket&#xff0c;Linux上的MySQL的客户端在不使用IP连…

【Stm32】从零建立一个工程

这里我们创建“STM32F103”系列的文件&#xff0c;基于“固件库” 1.固件库获取 https://www.st.com.cn/zh/embedded-software/stm32-standard-peripheral-libraries.html 2.使用Keil创建.uvprojx文件 前提是已经下载好了“芯片对应的固件” 3.复制底层驱动代码 将固件库下的…

LeetcodeTop100 刷题总结(一)

LeetCode 热题 100&#xff1a;https://leetcode.cn/studyplan/top-100-liked/ 文章目录 一、哈希1. 两数之和49. 字母异位词分组128. 最长连续序列 二、双指针283. 移动零11. 盛水最多的容器15. 三数之和42. 接雨水&#xff08;待完成&#xff09; 三、滑动窗口3. 无重复字符的…

每天一道面试题(15):谈谈你对CAS的理解

CAS&#xff08;Compare And Swap&#xff09;机制在并发编程中是一个非常重要的概念&#xff0c;主要用于实现原子性操作&#xff0c;避免使用传统的锁机制&#xff0c;从而提高性能。 CAS 的基本原理 CAS 的核心思想是通过比较当前值与预期值来决定是否执行修改。其流程如下…

嵌入式入门小工程

此代码基于s3c2440 1.点灯 //led.c void init_led(void) {unsigned int t;t GPBCON;t & ~((3 << 10) | (3 << 12) | (3 << 14) | (3 << 16));t | (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16);GPBCON t; }void le…

上位机图像处理和嵌入式模块部署(linux小系统开发)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 和若干年前相比较&#xff0c;现在嵌入式linux开发要简单得多。稍微贵一点的有树莓派&#xff0c;国产的有各种水果派&#xff0c;基本上都可以按照…

Google 扩展 Chrome 安全和隐私功能

过去一周&#xff0c;谷歌一直在推出新特性和功能&#xff0c;旨在让用户在 Chrome 上的桌面体验更加安全&#xff0c;最新的举措是扩展在多个设备上保存密钥的功能。 到目前为止&#xff0c;Chrome 网络用户只能将密钥保存到 Android 上的 Google 密码管理器&#xff0c;然后…