java----网络编程(一)

一.什么是网络编程

用户在浏览器中,打开在线视频网站,如优酷看视频,实质是通过网络,获取到网络上的一个视频资源。
在这里插入图片描述
与本地打开视频文件类似,只是视频文件这个资源的来源是网络。所谓网络资源就是网络中获取数据。而所有的网络资源,都是通过网络编程来进行数据传输的。网络编程,指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)。
在这里插入图片描述
当然,我们只要满足进程不同就行;所以即便是同一个主机,只要是不同进程,基于网络来传输数据,也属于网络编程。

发送端和接收端:
在一次网络数据传输时:发送端:数据的发送方进程,称为发送端。发送端主机即网络通信中的源主机。
接收端:数据的接收方进程,称为接收端。接收端主机即网络通信中的目的主机。
收发端:发送端和接收端两端,也简称为收发端。
注意:发送端和接收端只是相对的,只是一次网络数据传输产生数据流向后的概念。

在这里插入图片描述

请求和响应:

一般来说,获取一个网络资源,涉及到两次网络数据传输。第一次:请求数据的发送。第二次:响应数据的发送。

客户端和服务端:

服务端:在常见的网络数据传输场景下,把提供服务的一方进程,称为服务端,可以提供对外服务。
客户端:获取服务的一方进程,称为客户端。对于服务来说,一般是提供:
客户端获取服务资源和客户端保存资源在服务端。

在这里插入图片描述

常见的客户端服务端模型:

最常见的场景,客户端是指给用户使用的程序,服务端是提供用户服务的程序:1. 客户端先发送请求到服务端。2. 服务端根据请求数据,执行相应的业务处理。3. 服务端返回响应:发送业务处理结果。4. 客户端根据响应数据,展示处理结果(展示获取的资源,或提示保存资源的处理结果)

二.UDP和Tcp的特点

这里列举的UDP和Tcp只是很简单的一些特点,后面会详细谈论Tcp和UDP。

udp:无连接,不可靠,全双工,面向数据报。
tcp:有连接,可靠,全双工,面向字节流。

有连接和无连接:JDBC会先创建一个DataSource,再通过DataSource建立Connect连接。比如打电话时对方接通才算建立连接成功。
可靠和不可靠:A尽可能的给B传输信息,传输 失败时,A能感知到。可靠和不可靠都有优缺点,可靠传输效率低,不可靠传输效率高,具体用哪一个要看场景。
字节流和数据报:Tcp和文件操作类似,都是以字节传输的,像流一样。
UDP面向数据报,读写的单位是一个UDP数据报(后面介绍)。
全双工半双工:全双工,一个通道可以双向通信。半双工,一个通道只能单向通信。

三.UDP实现客户端服务器

2个核心类DatagramSocket和DatagramPacket

DatagramSocket

DatagramSocket是一个socket对象,操作系统使用文件这样的概念来管理一些软硬件资源。表示网卡的这类文件被称为socket文件,网卡也是操作系统使用文件来控制的。java的socket对象就对应着socket对象。
在这里插入图片描述
第一个构造方法用于客户端,第二个构造方法指定了端口号用于服务器。
为什么服务器要指定一个特定的端口号,而客户端要一个随机的端口号。
比如我要去学校食堂的2号窗口吃饭,学校就是服务器,我就是客户端。为了让学生每次都能找到,我窗口的位置必须是固定的,使用一个固定的端口号。而学生每次吃饭坐的位置不同,上次做的位置可能这次来被别人占用了,所以需要随机分配一个空闲的座位,也就是分配一个随机的端口号。
在这里插入图片描述

第一个方法是接收数据报,第二个发送数据报,第三个关闭。前2个方法都传入了DatagramPacket 类型的方法参数,那么DatagramPacke是什么?

DatagramPacke

DatagramPacke是一个UDP数据报,代表了系统中设定的UDP数据报的二进制形式。
在这里插入图片描述
DatagramPacket作为UDP数据报,必然要能够承载一些数据,通过手动指定byte[]作为数据的存储空间

实现Udp服务器

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

class UdpSever{
    public DatagramSocket socket =null;
    public UdpSever(int port) throws SocketException {
        this.socket=new DatagramSocket(port);
    }
    public void start() throws IOException {
        System.out.println("客户端启动");
        while (true){
            DatagramPacket datagramPacket = new DatagramPacket(new byte[1024],1024);
            socket.receive(datagramPacket);
            String str = new String(datagramPacket.getData(),0,datagramPacket.getLength());
           String requsrt = process(str);
           DatagramPacket datagramPacket1 = new DatagramPacket(requsrt.getBytes(),requsrt.getBytes().length,datagramPacket.getSocketAddress());
         socket.send(datagramPacket1);
            System.out.print("["+datagramPacket.getAddress().toString()+" ");
            System.out.print(datagramPacket.getPort()+"]:");
            System.out.print("req:"+str+" ");
            System.out.println("reqs:"+requsrt);
        }
    }
    public String process(String str){
        return str;
    }
}
public class Test3 {
    public static void main(String[] args) throws IOException {
 UdpSever udpSever = new UdpSever(9090);
 udpSever.start();
    }
}

在这里插入图片描述
创建DatagramPacket对象,传入字节数组,DatagramPacket的返回值是一个字节数组,第一句代码运行结束此时并没有把客户端发来的信息写入。socket.reveive才是把客户端发来的信息真正的写入创建的字节数组中。
在这里插入图片描述
因为写入字节数组的内容二进制形式,所以构造字符串把接收到的二进制内容转换为字符串。同时计算出响应。

UDP客户端

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

class Udpclint{
    public DatagramSocket socket=null;
    public String SeverIP;
    public int SeverPort;
    public Udpclint(String SeverIP,int SeverPort) throws SocketException {
        this.SeverIP=SeverIP;
        this.SeverPort=SeverPort;
        this.socket=new DatagramSocket();
    }
    public void start() throws IOException {
        System.out.println("客户端启动:");
        while(true){
            System.out.print("----->");
            Scanner scanner = new Scanner(System.in);
            String str = scanner.next();
            DatagramPacket datagramPacket = new DatagramPacket(str.getBytes(),str.getBytes().length, InetAddress.getByName(SeverIP),SeverPort);
           socket.send(datagramPacket);
           DatagramPacket datagramPacket1 = new DatagramPacket(new byte[1024],1024);
           socket.receive(datagramPacket1);
            String requst = new String(datagramPacket1.getData(),0,datagramPacket1.getLength());
            System.out.println(requst);
        }
    }

}
public class Test4 {
    public static void main(String[] args) throws IOException {
Udpclint udpclint = new Udpclint("127.0.0.1",9090);
udpclint.start();
    }
}

客户端和服务器相互搭配运行效果
在这里插入图片描述
在这里插入图片描述

根据客户端和服务器代码实现翻译功能

分析:字典功能需要客户端输入中文意思,服务器显示英文单词。只需要客户端在计算响应的时候,实现翻译处理,所以让自己实现的翻译类继承服务器类,重写计算响应的方法(process),使其具备翻译功能

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

class GrammerSever extends UdpSever{
    Map<String,String> map = new HashMap<>();
    public GrammerSever(int port) throws SocketException {
       super(port);
       map.put("猫","cat");
       map.put("狗","dog");
       map.put("鱼","fish");

    }

    @Override
    public String process(String str) {
        return map.get(str);
    }
}
public class Test5 {
    public static void main(String[] args) throws IOException {
        GrammerSever grammerSever = new  GrammerSever(9090);
        grammerSever.start();
    }
}

在这里插入图片描述
在这里插入图片描述

Tcp实现

Tcp分量要比Udp更重,用的更多的协议,,Tcp主要有2个类,SeverSocket和socket。给服务器用seversocket,socket既可以客户端使用也可以服务器使用。

Tcp服务器

mport java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class TcpSever{
    public ServerSocket socket = null;
    public ExecutorService executorService = Executors.newCachedThreadPool();
    public TcpSever(int port) throws IOException {
        this.socket=new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动:");

        while(true){
            Socket socket1 = socket.accept();
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        process(socket1);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            });


        }
    }
    public void process(Socket socket1) throws IOException {
        System.out.printf("[%s:%d] 客户端上线!\n", socket1.getInetAddress().toString(), socket1.getPort());
        try(InputStream inputStream = socket1.getInputStream();
            OutputStream outputStream = socket1.getOutputStream()) {
            while (true){
                Scanner scanner =new Scanner(inputStream);
                if(!scanner.hasNext()){
                    System.out.printf("[%s:%d] 客户端下线!\n", socket1.getInetAddress().toString(), socket1.getPort());
                    break;
                }
                String requst = scanner.next();
                String requse = process1(requst);
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(requse);
                printWriter.flush();
                System.out.printf("[%s:%d] req: %s, resp: %s\n", socket1.getInetAddress().toString(), socket1.getPort(),
                        requse, requst);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        finally {
            socket1.close();
        }
    }
    public  String process1(String str){
        return str;
    }
}
public class Test {
    public static void main(String[] args) throws IOException {
TcpSever tcpSever = new TcpSever(22);
tcpSever.start();
    }
}

在这里插入图片描述
Tcp首先要处理连接,内核的连接就想一个待办事项,这些待办事项在一个队列的数据结构中,应用程序就需要一个一个完成这些任务,要完成这些任务就得先取任务。
在这里插入图片描述
accept是把内核中已经建立好的连接拿到应用程序中,但是这里的返回值并非是一个connect这样的对象,而只是一个socket对象,这个socket对象就像一个耳麦一样可以说话也可以听到对方的声音。
在这里插入图片描述

Tcp客户端

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

class Tcpclint{
    public Socket socket =null;
    public Tcpclint(String IP,int port) throws IOException {
        this.socket=new Socket(IP,port);
    }
    public void start(){
        System.out.println("客户端启动:");
        try(InputStream inputStream = socket.getInputStream();
            OutputStream outputStream =socket.getOutputStream()) {
            while (true) {
                System.out.print("-------->");
                Scanner scanner = new Scanner(System.in);
                String str = scanner.next();
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(str);
                printWriter.flush();
                Scanner scanner1 = new Scanner(inputStream);
                String str1 = scanner1.next();
                System.out.println(str1);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
public class Test2 {
    public static void main(String[] args) throws IOException {
        Tcpclint tcpclint = new Tcpclint("127.0.0.1",22);
        tcpclint.start();
    }
}

在这里插入图片描述
在这里插入图片描述

Tcp实现单词翻译功能

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

class Grammer extends  TcpSever{
    Map<String,String> map = new HashMap<>();
    public Grammer(int port) throws IOException {
        super(port);
        map.put("猫","cat");
        map.put("狗","dog");
        map.put("鱼","fish");
    }

    @Override
    public String process1(String str) {
        return map.get(str);
    }
}
public class Test7 {
    public static void main(String[] args) throws IOException {
        Grammer grammer =new Grammer(9090);
        grammer.start();
    }
}

在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringTask实现的任务调度与XXL-job实现的分布式任务调度【XXL-Job工作原理】

目录 任务调度 分布式任务调度 分布式任务调度存在的问题以及解决方案 使用SpringTask实现单体服务的任务调度 XXL-job分布式任务调度系统工作原理 XXL-job系统组成 XXL-job工作原理 使用XXL-job实现分布式任务调度 配置调度中心XXL-job 登录调度中心创建执行器和任务 …

安装OpenEBS,镜像总是报错ImagePullBackOff或者ErrImagePull的解决方法

按照 KubeSphere 官方文档安装 OpenEBS&#xff0c;镜像总是报错ImagePullBackOff或者ErrImagePull的解决方法 helm 有很多更换 源 的文章&#xff0c;有一些是写更换阿里云的源&#xff0c;但是阿里云的源根本没更新OpenEBS的镜像。 在网上找到1个可用的源&#xff1a; 可用的…

nodejs pkg打包跨平台执行文件,带.node插件

在nodejs引入的第三方库中,大部分插件都是nodejs原生开发,使用pkg可以快速打包,生成windows、linux(ubuntu、centOS等)、麒麟系统下面执行文件。遇到了第三方插件gdal、sharp、sqlite3,在webstorm中打包生成执行文件,跨平台部署的时候会出现找不到###.node文件,需要获取部…

BUUCTF-----[CISCN 2019 初赛]Love Math

<?php error_reporting(0); //听说你很喜欢数学&#xff0c;不知道你是否爱它胜过爱flag if(!isset($_GET[c])){show_source(__FILE__); }else{//例子 c20-1$content $_GET[c];if (strlen($content) > 80) {die("太长了不会算");}$blacklist [ , \t, \r, \n…

Employing Multi-Estimations for Weakly-Supervised Semantic Segmentation

eighted selective training (WST) 辅助信息 作者未提供代码

《手把手教你》系列技巧篇(三十七)-java+ selenium自动化测试-日历时间控件-上篇(详解教程)

1.简介 我们在实际工作中&#xff0c;有可能遇到有些web产品&#xff0c;网页上有一些时间选择&#xff0c;然后支持按照不同时间段范围去筛选数据。网页上日历控件一般&#xff0c;是一个文本输入框&#xff0c;鼠标点击&#xff0c;就会弹出日历界面&#xff0c;可以选择具体…

x6.js 从流程图组件库中拖拽组件到画布dnd使用

上一篇已经了解到了x6.js常用功能以及使用方法。但我们使用流程图的时候还少不了一个非常重要的功能那就是拖拽组件库里的组件进来。如下图&#xff1a; 首先是布局这块&#xff0c;拖拽组件库的视图中布局无需我们去写&#xff0c;我们只需把界面搭建好。 添加组件库 1.搭建布…

LeetCode 0310.最小高度树:拓扑排序秒了

【LetMeFly】310.最小高度树&#xff1a;拓扑排序秒了 力扣题目链接&#xff1a;https://leetcode.cn/problems/minimum-height-trees/ 树是一个无向图&#xff0c;其中任何两个顶点只通过一条路径连接。 换句话说&#xff0c;一个任何没有简单环路的连通图都是一棵树。 给你…

JavaScript 进阶(一)

一、作用域 作用域&#xff08;scope&#xff09;规定了变量能够被访问的“范围”&#xff0c;离开了这个“范围”变量便不能被访问。 作用域分为&#xff1a; 局部作用域 、全局作用域。 1.1局部作用域 局部作用域分为函数作用域和块作用域。 1. 函数作用域&#xff1a; 在函数…

力扣刷题Days20-151. 反转字符串中的单词(js)

目录 1,题目 2&#xff0c;代码 1&#xff0c;利用js函数 2&#xff0c;双指针 3&#xff0c;双指针加队列 3&#xff0c;学习与总结 1&#xff0c;正则表达式 / \s /&#xff1a; 2&#xff0c;结合使用 split 和正则表达式&#xff1a; 1,题目 给你一个字符串 s &am…

[漏洞分析]Fortinet FortiNAC CVE-2022-39952简析

Fortinet FortiNAC CVE-2022-39952简析 一、影响版本二、概况三、利用CVE-2022-39952四、POC 一、影响版本 FortiNAC 9.4.0 FortiNAC 9.2.0 - 9.2.5 FortiNAC 9.1.0 - 9.1.7 FortiNAC 8.3 - 8.8 二、概况 Fortinet 在其安全公告中表示&#xff0c;他们在keyUpload script…

深入解析红黑树(RB-Tree):原理、操作及应用

文章目录 一、红黑树的特点与性质二、红黑树的实现1、实现红黑树的插入操作2、红黑树的验证方法a. Check 函数b. IsBalance 函数 红黑树作为一种自平衡的二叉搜索树&#xff0c;在计算机科学领域中占据着重要的地位。它的设计旨在在维持树的平衡性的同时&#xff0c;保证各种操…

【JavaScript】JavaScript 运算符 ⑤ ( 赋值运算符 | 基础赋值运算符 与 复合赋值运算符 )

文章目录 一、JavaScript 赋值运算符1、赋值运算符 概念2、基础赋值运算符 与 复合赋值运算符3、复合赋值运算符4、完整代码示例 一、JavaScript 赋值运算符 JavaScript 赋值运算符种类 : 基础赋值运算符 : 等于 : ; 复合赋值运算符 : 加等 : 减等 : -乘等 : *除等 : /取模等…

基于springboot+vue的房屋交易平台

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

App拉新必备!Xinstall渠道追踪,让每一分钱都花在刀刃上

在移动互联网时代&#xff0c;App已经成为人们日常生活中不可或缺的一部分。然而&#xff0c;对于App开发者来说&#xff0c;如何有效地进行拉新&#xff0c;提高用户留存率&#xff0c;一直是一个难题。而渠道追踪&#xff0c;作为App推广过程中的重要环节&#xff0c;往往被忽…

029—pandas 遍历行非向量化修改数据

前言 在 pandas 中&#xff0c;向量化计算是指利用 pandas 对象的内置方法和函数&#xff0c;将操作应用到整个数据结构的每个元素&#xff0c;从而在单个操作中完成大量的计算。 但在一些需求中&#xff0c;我们无法使用向量化计算&#xff0c;就需要迭代操作&#xff0c;本例…

前端三件套 | 综合练习:模拟抽奖活动,实现一个简单的随机抽取并显示三名获胜者

随机运行结果如下&#xff1a; 参考代码如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><tit…

通俗易懂的Python循环讲解

循环用于重复执行一些程序块。从上一讲的选择结构&#xff0c;我们已经看到了如何用缩进来表示程序块的隶属关系。循环也会用到类似的写法。 for循环 for循环需要预先设定好循环的次数(n)&#xff0c;然后执行隶属于for的语句n次。 基本构造是 for 元素 in 序列: statemen…

常用芯片学习——BME280芯片

BME280 温湿度气压传感器 芯片介绍 BME280是基于成熟传感原理的组合数字湿度、压力和温度传感器。该传感器块采用极为紧凑的金属盖LGA封装&#xff0c;占地面积仅为2.5x2.5mm2&#xff0c;高度为0.93mm。该传感器提供I2C以及SPI接口。它的小尺寸和低功耗允许在电池驱动的设备…

如何写好Stable Diffusion的prompt

Stable Diffusion是一种强大的文本到图像生成模型&#xff0c;其效果在很大程度上取决于输入的提示词&#xff08;Prompt&#xff09;。以下是一些关于如何编写有效的Stable Diffusion Prompt的秘诀&#xff1a; 明确描述&#xff1a;尽量清晰地描述你想要的图像内容。使用具体…
最新文章