【网络编程】UDP实现回显服务器

news2024/11/23 19:34:57

一.网络编程的基本术语.

  • 客户端

客户端是为用户提供本地服务的程序,通常位于用户设备上。也称为用户端,是相对于服务器而言的。它主要指安装在用户设备上的程序,这些程序能够与服务器进行通信,从而获取服务或者执行特定功能。在互联网应用中,常见的客户端包括网页浏览器、电子邮件客户端和即时通讯软件等。它们需要与远端的服务器建立连接,以便接收如数据库服务、邮件服务等网络服务。

  • 服务器

服务器则是为其他程序或设备提供功能的计算机或软件。一种专门设计用来处理数据请求并提供服务的计算设备。它具备高速的CPU、大容量的存储空间以及强大的I/O吞吐能力,能够长时间稳定运行。服务器的主要作用是在网络中为客户机(如个人电脑、智能手机等)提供诸如网站访问、文件存储、数据处理等各种计算和应用服务。

  • 网络编程

网络编程 : 指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)。

  • 套接字(Socket)

套接字,常称为socket,是计算机网络中用于实现不同主机之间的进程双向通信的端点。在网络编程中,套接字充当了非常重要的角色,它定义了一套标准的API,允许程序员在不同的计算机之间发送和接收数据.是网络编程中实现不同主机间进程通信的一种技术规范和编程接口。

  • 流套字节

使用传输层TCP协议 , 对于字节流来说,可以简单的理解为,传输数据是基于IO流,流式数据的特征就是在IO流没有关闭的情况下,是无边界的数据,可以多次发送,也可以分开多次接收。

  • 数据报套接字

使用传输层UDP协议 , 对于数据报来说,可以简单的理解为,传输数据是⼀块⼀块的,发送⼀块数据假如100个字节,必须⼀次发送,接收也必须⼀次接收100个字节,而不能分100次,每次接收1个字节。

  • 原始套字节

原始套接字用于自定义传输层协议,用于读写内核没有处理的IP协议数据。

  • TCP和UDP的特点

TCP特点:

  1. 有连接 : 连接的双方都需要认同(本质上就是通信双方都保存有通信双方各自的信息)
  2. 可靠传输 : 主要是指发送方放的信息是否被收到 , 发送方能够清楚的感知到.
  3. 面向字节流 : 传输的基本单位是以字节为基本单位
  4. 全双工 : 一个信道,可以双向通信. 只能单向通信就称为’‘半双工’’

UDP的特点:
1.无连接. 2. 不可靠传输. 3.面向字节报 4.全双工.

二.常用API

DatagramSocket
构造方法:
在这里插入图片描述
常用方法:
在这里插入图片描述
DatagramPacket
构造方法:
在这里插入图片描述
基本方法:
在这里插入图片描述

三.基于UDP回显服务器.

客户端代码

package Demo1;

import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class udpEchoClint {
    private DatagramSocket datagramSocket = null;
    private String  serverIP;
    private int serverPort;
    //客户端要给服务器发送请求的前提就是知道服务器的地址
    public udpEchoClint(String serverIP,int serverPort) throws SocketException {
        datagramSocket = new DatagramSocket();
        this.serverIP= serverIP;
        this.serverPort = serverPort;
    }
    public void start() throws IOException {
        System.out.println("客户端启动~~");
        Scanner scanner = new Scanner(System.in);
        while(true){
            System.out.print("->");
            if(!scanner.hasNext()){
                break;
            }
            //1.从控制台读取要发送的请求数据.
            String request = scanner.next();
            //2.构造一个请求并发送.
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(StandardCharsets.UTF_8),
                    request.getBytes().length,
                    InetAddress.getByName(serverIP),
                    serverPort
                    );
            datagramSocket.send(requestPacket);
            //3.读取服务器的响应.
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
            datagramSocket.receive(responsePacket);
            //4.把响应显示到控制台上
            String response = new String(responsePacket.getData(),0,responsePacket.getLength());
            System.out.println(response);
        }
    }
    public static void main(String[] args) throws IOException {
        udpEchoClint clint = new udpEchoClint("127.0.0.1",9090);
        clint.start();
    }
}

服务器代码

package Demo1;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

public class udpEchoServer {
    private DatagramSocket datagramSocket = null;
    public udpEchoServer(int port) throws SocketException {
        datagramSocket = new DatagramSocket(port);
    }
    //服务器的启动逻辑.
    public void start() throws IOException {
        System.out.println("服务器启动!!");
        //对于服务器来说,需要不停的收到请求,返回响应

        while(true){
            //每次循环就是处理一个请求返回响应的过程
            //1.读取请求并解析
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
                //这个字节数组,保存收到的消息正文(应用层数据包),也就是应用层数据报的载荷部分
            datagramSocket.receive(requestPacket);
                //将消息正文转化为字符串.
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());
            //2.根据请求计算响应(对于回显服务器来说,这一步啥也不用干)
            String response = process(request);
            //3.把响应返回给客户端
            //构造一个响应对象.
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(StandardCharsets.UTF_8),
                    response.getBytes().length,
                    requestPacket.getSocketAddress() //得到一个INetAddress对象吗,里面存储了客户端的IP和端口号.
                    // 会把客户端的源IP和端口号,作为目的IP和目的端口号.

            );
            datagramSocket.send(responsePacket);

            //打印日志:
            System.out.printf("[%s,%d],request: %s, response: %s",
                    responsePacket.getAddress().toString(),
                    responsePacket.getPort(),
                    request,
                    response
            );
        }
    }
    public String process(String request){
        //回显服务器,返回要求.
        return request;
    }
    public static void main(String[] args) throws IOException {
        udpEchoServer server = new udpEchoServer(9090);
        //1024<端口号范围<65535
        server.start();
    }
}

运行结果:
在这里插入图片描述
在这里插入图片描述
具体的执行流程:

  1. 服务器启动===>启动之后,立即进入while循环,执行到receive,进入阻塞,此时客户端还没有发来请求~~
  2. 客户端启动===>启动之后,立即进入while虚幻,执行到hasNext这里~~进入阻塞,此时用户没有在控制台输入任何内容.
  3. 用户在客户端的控制台中输入字符串,按下回车.此时hasNext阻塞解除,next会返回刚才输入的内容.
    基于用户输入的内容,构造出一个DatagramPacket对象,并进行send~~
    send执行完毕之后,继续执行到receive操作,等待服务器返回的响应数据(此时服务器还没有返回响应,这里也会阻塞).
  4. 服务器收到请求之后,就会从receive的阻塞中返回.
    返回之后,就会根据读到的DatagramPacket对象,构造String request,通过process方法构造一个String response
    再根据response构造一个DatagramPacket表示响应对象,再通过send来进行发送给客户端
    执行这个过程中,客户端也始终在阻塞等待!!
  5. 客户端从receive中返回执行,就能够得到服务器返回的相应.并且打印在控制台上.
    于此同时,服务器进入下一次循环,也要进入到第二次的receive阻塞,等待下个请求~~

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

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

相关文章

window轻松使用k8s

Docker Desktop安装篇 1、win安装 1、下载安装包 https://www.docker.com/products/docker-desktop/ 官网下载安装包 2、配置win支持虚拟化 不勾选Hyper-V&#xff0c;它和Windows Subsystem for Linux (WSL) 是两套功能&#xff0c;这里不选他 3、安装WSL配置window支持lin…

6-pytorch - 网络的保存和提取

前言 我们训练好的网络&#xff0c;怎么保存和提取呢&#xff1f; 总不可以一直不关闭电脑吧&#xff0c;训练到一半&#xff0c;想结束到明天再来训练&#xff0c;这就需要进行网络的保存和提取了。 本文以前面博客3-pytorch搭建一个简单的前馈全连接层网络&#xff08;回归问…

Level protection and deep learning

1.模拟生成的数据 import randomdef generate_data(level, num_samples):if level not in [2, 3, 4]:return Nonedata_list []for _ in range(num_samples):# 构建指定等级的数据data str(level)for _ in range(321):data str(random.randint(0, 9))data_list.append(data)…

2.4G漂移小车电子方案 酷得智能科技

漂移高速遥控车是一种专门设计用于执行高速漂移动作的遥控车模型。以下是一些关于漂移高速遥控车的功能介绍&#xff1a; 1、高速性能&#xff1a;漂移车通常配备有强力的电机和电池&#xff0c;以便在保持高速的同时进行漂移动作。 2、漂移能力&#xff1a;漂移车的轮胎和悬挂…

操作系统—实现可变式分区分配算法

文章目录 实现可变式分区分配算法1.实验环境2.如何在xv6中实现分区分配算法&#xff1f;(1).xv6的内存管理机制(2).实现思路 3.最佳适应算法(1).基本思路(2).步骤(3).测试&Debug 总结参考资料 实现可变式分区分配算法 1.实验环境 因为这一次的实验仍然是在xv6中进行&#…

【AIGC】AIGC在虚拟数字人中的应用:塑造未来互动体验的革新力量

&#x1f680; &#x1f680; &#x1f680;随着科技的快速发展&#xff0c;AIGC已经成为引领未来的重要力量。其中&#xff0c;AIGC在虚拟数字人领域的应用更是引起了广泛关注。虚拟数字人作为一种先进的数字化表达形式&#xff0c;结合了3D建模、动画技术、人工智能等多种先进…

PaddleOCR训练自己模型(2)----参数配置及训练

一、介绍 paddleocr分为文字定位(Det)和文字识别(Rec)两个部分 二、定位模型训练 &#xff08;1&#xff09;Det预训练模型下载&#xff1a;https://paddleocr.bj.bcebos.com/PP-OCRv4/chinese/ch_PP-OCRv4_det_train.tar &#xff08;2&#xff09;下载完之后&#xff0c;…

女上司问我:误删除PG百万条数据,可以闪回吗?

作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验 擅长主流数据Oracle、MySQL、PG、openGauss运维 备份恢复&#xff0c;安装迁移&#xff0c;性能优化、故障应急处理等可提供技术业务&#xff1a; 1.DB故障处理/疑难杂症远程支援 2.Mysql/PG/Oracl…

32. BI - 依据淘宝的用户行为,从 0 开始实现一个简单的移动推荐系统

本文为 「茶桁的 AI 秘籍 - BI 篇 第 32 篇」 Hi, 你好。我是茶桁。 今天咱们要来完成一个简单的推荐系统的建立。 之前的课程里给大家讲了两种模型&#xff0c;也希望大家对模型的概念以及使用场景会有些了解。不光是推荐系统&#xff0c;在生物、心理学、社交网络等等里面都…

LangChain-Chatchat 开源知识库来了

LangChain-Chatchat 开源知识库来了 LangChain-Chatchat 架构设计LangChain-ChatChat 具体实现过程 一键本地离线部署软件环境硬件环境支持三种部署方式 LangChain-Chatchat 是基于 ChatGLM 等大语言模型与 LangChain 等应用框架实现&#xff0c;开源、可离线部署的 RAG 检索增…

安全特低电压 SELV(Safety Extra Low Voltage,缩写SELV) 是不接地系统的安全特低电压

SELV LED驱动器 市场上有很多LED灯是非隔离的&#xff0c;甚至还有灯条要100多伏特电压才能点亮的&#xff0c;安全吗&#xff1f; 国外多数LED驱动器标注了SELV&#xff0c;为什么&#xff1f; 安全特低电压 SELV(Safety Extra Low Voltage&#xff0c;缩写SELV) 是不接地系…

通过adb 命令打印安装在第三方模拟器上的log

1&#xff0c;环境&#xff1a;Windows 11 &#xff0c;第三方模拟器 网易的MuMu 步骤&#xff1a; 1&#xff0c;打开cmd&#xff0c;输入 adb connect 172.0.0.1:7555 2&#xff0c;在cmd&#xff0c;再次输入adb logcat 回车

MongoDB的CURD(增删改查操作)

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 ✈️如果喜欢这篇文章的话 &#x1f64f;大大们可以动动发财的小手&#x1f449;&#…

初步学习node.js文件模块

环境已安装好&#xff1b; 写一个read1.js如下&#xff1b; var fs require("fs"); var data ;// 创建一个流 var stream1 fs.createReadStream(test1.jsp); stream1.setEncoding(UTF8);// 绑定data事件 stream1.on(data, function(mydata) {data mydata; });/…

竞赛 基于GRU的 电影评论情感分析 - python 深度学习 情感分类

文章目录 1 前言1.1 项目介绍 2 情感分类介绍3 数据集4 实现4.1 数据预处理4.2 构建网络4.3 训练模型4.4 模型评估4.5 模型预测 5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于GRU的 电影评论情感分析 该项目较为新颖&#xff0c;适合作为竞…

注册表让我重回80年代(狗头保命

现在是2024年4月16日23:09:07&#xff0c;今天之所以这么晚才睡&#xff0c;是因为遇到了一个很有意思的事情&#xff0c;以至于解决完之后&#xff0c;强挺困意&#xff0c;将其记录—— 缘由是想只用键盘操纵电脑&#xff0c;上面有写&#xff0c;那用winR就是家常便饭。只不…

贴片滚珠振动开关 / 振动传感器的用法

就是这种小东西&#xff1a; 上面的截图来自&#xff1a;https://item.szlcsc.com/3600130.html 以前写过一篇介绍这种东西内部的结构原理&#xff1a;贴片微型滚珠振动开关的结构原理。就是有个小滚珠会接通开关两边的电极&#xff0c;振动时滚珠会在内部蹦跳&#xff0c;开关…

基于Springboot的影城管理系统

基于SpringbootVue的影城管理系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页展示 电影信息 电影资讯 后台登录页 后台首页 用户管理 电影类型管理 放映…

RabbitMQ Stream插件使用详解

2.4版为RabbitMQ流插件引入了对RabbitMQStream插件Java客户端的初始支持。 RabbitStreamTemplateStreamListener容器 将spring rabbit流依赖项添加到项目中&#xff1a; <dependency><groupId>org.springframework.amqp</groupId><artifactId>sprin…

WebKit内核游览器

WebKit内核游览器 基础概念游览器引擎Chromium 浏览器架构Webkit 资源加载这里就不得不提到http超文本传输协议这个概念了&#xff1a; 游览器多线程HTML 解析总结 基础概念 百度百科介绍 WebKit 是一个开源的浏览器引擎&#xff0c;与之相对应的引擎有Gecko&#xff08;Mozil…