【计算机网络】socket编程

文章目录

  • 1. 网络通信的理解
  • 2.进程PID可以取代端口号吗?
  • 3. 认识TCP协议
  • 4. 认识 UDP协议
  • 5. socket编程接口
    • udp_server.hpp的代码解析
      • socket——创建 socket 文件描述符
      • Initserver——初始化
        • 1.创建套接字接口,打开网络文件
          • bind——绑定的使用
        • 2.给服务器指明IP地址和端口号
          • struct sockaddr_in的理解
          • bzero 清空
          • 代码实现
          • inet_addr ——字符串风格转化为4字节风格
          • 服务器自己指定IP地址
        • 3. 云服务器,或者一款服务器,一般不要指明某一个确定的IP
      • start ——启动
        • 1. 收到客户端发来的消息
          • recvfrom——获取用户数据报
          • inet_addr ——将4字节风格转为字符串风格
        • 2.将消息发给别人
          • sendto
    • udp_client.cc的代码解析
      • 客户端如何绑定?
      • 服务器为什么要自己绑定?
      • 代码实现
    • 完整代码
      • err.hpp (枚举错误码)
      • makefile
      • udp_client.cc(客户端的实现,无封装)
      • udp_clinet.hpp
      • udp_server.cc (有封装)
      • udp_server.hpp(服务器的实现)

1. 网络通信的理解

主机A将自己的数据交给主机B,就需要给主机B发送消息,主机B未来要给主机A回消息

但实际上 主机A将自己的数据交给主机B 并不是最终目的

如:你在淘宝上买了一件衣服,卖家发货后,从广东省发货 到 你所在的地区 ,最终包裹成功到达你的手上,你还需要决定这个快递该怎么用

数据的传送不是目的,让两台主机通过数据进行通信来协同完成任务才是目的


如:唐僧说要去西天去取经,唐僧所对应的寺庙是A主机,西天的大雷音寺是B主机,唐僧并不是到大类饮食就完了,这只是他的手段,
他还需要面见如来,如来会提供给他经书的服务


数据发起时,从主机A的传输层开始,交给主机B的传输层
而数据是从主机A的应用层中的某种客户端传来的
而将数据交给主机B的传输层不是直接目的,要把数据再交给应用层 中的某种服务器

主机A对应的客户端一定要启动起来,所以其本质是 进程

因为主机B的某种服务器在以进程的方式运行,所以可以随时随地能够访问某种服务

网络通信的本质是 进程间的通信


通信的第一个阶段:先将数据通过操作系统,将数据发送到目标主机(手段)
通信的第二个阶段:在本主机将收到的数据,推送给自己上层的指定进程

第一个阶段 可以通过TCP/IP协议完成,因为IP可以表示互联网上唯一的一台主机

当主机B的传输层把数据交给应用层,应用层对应的进程非常多
所以为了标识自己主机上网络进程的唯一性,提出了 端口号 的概念

端口号是传输层协议的字段,是一个2个字节16位的整数,用来标识系统层面上进程的唯一性

所以 IP地址 + 端口号 可以表示 互联网中唯一的一个进程

通信时,是有两个进程进行通信,所以就有源IP 和源 端口号 以及 目标IP 和目标 端口号
源IP 和源 端口号表示 互联网中唯一的一个进程
目标IP 和目标 端口号也表示 互联网中唯一的一个进程

所以 网络通信的本质 是通过IP+PORT号 构建唯一性,来进行网络进程间通信, 简称 套接字通信

2.进程PID可以取代端口号吗?

进程PID在系统层面上每个进程也是唯一的,也能表示该系统上进程的唯一性,所以用进程PID可以代替端口号的
但会存在一些问题
1.不是所有的进程都要进行网络通信,只有部分进程可能会网络通信,若用进程PID来作为网络标识该进程,就很难区分清楚那些是进行网络通信的,那些不是进行网络通信的

2. PID是操作系统进程管理的概念,网络模块也要包含进程管理的部分,要不然无法认识PID
增加了系统当中进程管理和网络管理的耦合度

3. 认识TCP协议

TCP协议(Transmission Control Protocol) 传输控制协议
特点:
传输层协议
面向连接
在通信过程中,会自带可靠性
面向字节流
在进行发和收数据时,在TCP层没有报文的概念,收到一堆的数据,把这一堆的东西一次将给上层的应用层,也可一个字节一个字节交
字节数据如何解释TCP不关心,只关心要都多少,给你多少,最终解释信息由应用层自己解释,这种从称之为字节流

4. 认识 UDP协议

UDP协议(User Datagram Protocol)用户数据报协议
特点:
传输层协议
无连接
不可靠传输
面向数据报
如:收快递,收一个就是一个完整的快递,具体的快递不可能收半个或者一个半,若对方发了三次,你就必须收三次

5. socket编程接口

实验室做出来一套进程间通信的标准,既可在本地通信,又可以在网络跨主机通信的标准 即 socket标准 隶属于 posix标准

最常见的为 基于网络通信的套接字 sockaddr_in

预间套接字 (使用在两个进程间使用本地进程通信的) sockaddr_un

套接字的设计者为了能够让所有人以 一套接口的方式 既能本地通信 又能网络通信,
所以设计出一个公共的数据结构 叫做 struct sockaddr
若想进行网络通信 (struct sockaddr_in) 或者 进行 本地通信 (struct sockaddr_un) ,使用 sockaddr 进行强制转换即可


在结构最开始时,都要有16位的地址类型
AF_INET 与AF_UNIX 实际上都是宏,用整数来表示的
将地址进行比较判断,
若等于 AF_INET,就为网络通信,把 sockaddr强转为 sockaddr_in
若等于 AF_UNIX,就为本地通信,把 sockaddr强转为 sockaddr_un


udp_server.hpp的代码解析

通过网络协议栈的通信功能 ,来把数据交付给对方的应用层,来完成双方进程的通信

将客户端的数据交给 服务端 ,就需要给服务端发送消息,服务端再给客户端回消息


在 udp_server.hpp 中 使用namspace 将命名空间 命名为 ns_server
其中再定义一个类 udpserver

socket——创建 socket 文件描述符

输入 man socket创建套接字

第一个参数 domain ,用于区分 进行网络通信还是 本地通信
若想为网络通信,则使用 AF_INET
若想为本地通信,则使用 AF_UNIX

第二个参数 type, 套接字对应的服务类型

在这里插入图片描述

SOCK_STREAM 流式套接
SOCK_DGRAM 无连接不可靠的通信(用户数据报)

第三个参数 protocol ,表示想用那种协议,协议默认为0
若为 流式套接,则系统会认为是TCP协议 ,若为用户数据报,则系统会认为是UDP协议

套接字的返回值:若成功则返回文件描述符,若失败则返回 -1

Initserver——初始化

1.创建套接字接口,打开网络文件

在这里插入图片描述
使用socket套接字,创建出 网络通信、UDP协议
若套接字返回-1表示失败,则初始化也就失败,程序就没有必要在继续运行了,所以使用exit终止程序

若套接字创建成功,则返回文件描述符
文件描述符的前三个分别被 标准输入 标准输出 标准错误占用,所以此时的文件描述符应该打印出3

bind——绑定的使用

输入 man 2 bind ,查看绑定

给一个套接字绑定一个名字
第一个参数 sockfd 为 文件描述符
第二个参数 addr 为 通用结构体类型
第三个参数 addrlen 为 第二个参数的实际长度大小

bind返回值:若成功,则返回0,若失败,返回 -1

2.给服务器指明IP地址和端口号

想要使用struct sockaddr_in类型 需添加头文件

定义一个 struct sockaddr_in(网络通信) 类型的 变量 local

struct sockaddr_in的理解

在这里插入图片描述
将 struct sockaddr_in 转到定义
16位地址类型:将 sa_prefix替换成 sin_ ,sin## family 实际上为 sin_family
此时的 sin_port 对应 当前绑定的端口号
sin_addr对应的是IP地址
再次将 in_addr转到定义,IP地址就是一个32位的整数

bzero 清空

sin_zero 作为 该结构体的填充字段
结构体可能很大,用不完,则使用填充字段将其填充上即可

输入 man bzero

将有n个字节的缓冲区,全部写为0

代码实现

在这里插入图片描述

将local对应的family(16位地址类型) 设置为 网络通信


设置一个私有的端口号port_


在这里插入图片描述
在类外设置一个端口号,用于构造时,若没有端口号传入,则8082充当缺省值


若我给你发消息,未来也需要将消息发回来,所以就必须知道我的IP地址和端口号
即端口号 以报文的形式发送到网络中

类内定义的port_,被称为本地主机序列, 需要把这个port_从主机序列 转成网络序列

输入 man htons ,表示短整数的主机转网络序列



定义一个私有的变量 ip_ 由于我们设置的IP地址是字符串风格的,而系统中的IP地址是4字节风格的 所以就需要将字符串风格的转化为 4字节风格的
inet_addr ——字符串风格转化为4字节风格

输入 man inet_addr

作用为:将字符串风格的IP地址 转化为 4字节风格的IP地址,并 默认会把主机序列 转换为 网络序列


由于local实际上定义在用户层的栈上,并没有在内核

所以借助bind,将填充好的套接字字段和文件字段,进行绑定关联,这样的文件才是网络文件
由于local 是 struct sock_addr_in 类型 ,需要强转为 struct sockaddr 公共类型


服务器自己指定IP地址

此时运行 udp_server可执行程序,会发现套接字创建成功,但绑定会失败


云服务器 不需要bind IP地址,需要让服务器自己指定IP地址


所以在main函数中添加命令行参数
命令行参数
main函数的两个参数,char* argv[] 为指针数组 ,argv为一张表,包含一个个指针,指针指向字符串
int argc,argc为数组的元素个数

设计一个usage函数,用以表示出 出现问题的可执行程序的名字 proc


再次创建一个err.hpp,使用enum枚举,将USAGE_ERR设置成1 ,默认将SOCKET_ERR(套接字报错)设置为2,
将 BIND_ERR(绑定错误)设置为3


通过argv数组的第二个下标指明字符串风格的端口号,再通过atoi将字符串转化为整数
最终只传入 端口号即可


在这里插入图片描述

3. 云服务器,或者一款服务器,一般不要指明某一个确定的IP

在这里插入图片描述

使用 INADDDR_ANY , 让udpserver在启动的时候,bind本主机上的任意IP


将 INADDDR_ANY 转到定义,实际上为缺省的0值


start ——启动

服务器本质是一个死循环,永远不退出
如:半夜打开王者荣耀,依旧可以玩


1. 收到客户端发来的消息

recvfrom——获取用户数据报

输入 man recvfrom, 获取用户数据报

第一个参数 sockfd 为 套接字
第二个参数 buf 为 自己定义的缓冲区
第三个参数 len 为 缓冲区的长度
第四个参数 flags 为读取方式,默认设为0,以阻塞方式读取
剩余两个参数 src_addr 和 addrlen 为 输入 输出型 参数
使用recvfrom收到数据,最终还要把数据还回去,想要还回去就必须知道别人是谁
src_addr 为 作为一个结构体,内部记录客户端的IP地址和端口号
addrlen 为 输出时结构体的大小
返回值:若大于0,则读取成功


定义一个 struct sockaddr_in(网络通信) 类型的 变量 peer
使用 len 来表示 未来的结构体大小

若n大于0,则读取成功,将最后一个位置的下一个位置设为\0
若读取失败,则继续读取


peer下的IP地址为 4字节整数,需要将其转为字符串风格

inet_addr ——将4字节风格转为字符串风格

输入 man inet_addr,将4字节IP转为字符串风格的IP


peer下的端口号为网络序列,想要获取客户端的端口号 clientport,需要使用 ntohs 将网络序列转为主机序列

2.将消息发给别人

sendto

输入 man sendto

第一个参数 sockfd 为 套接字
第二个参数 buf 为 自己定义的缓冲区
第三个参数 len 为 缓冲区的长度
第四个参数 flags 为读取方式,默认设为0,以阻塞方式读取
剩余两个参数 src_addr 和 addrlen 为 输入 输出型 参数
使用recvfrom收到数据,最终还要把数据还回去,想要还回去就必须知道别人是谁
src_addr 为 将以前收到的消息转会给客户端
addrlen 为 输出时结构体的大小
返回值:若大于0,则读取成功



udp_client.cc的代码解析

第一个参数 使用 AF_INET,表示网络通信
第二个参数 使用SOCK_DRAM,表示数据报
第三个参数 默认设为0,由于上述为数据报,所以为UDP协议


客户端如何绑定?

客户端是需要绑定的
socket通信的本质 是 客户端的IP与端口号 与 服务器的IP与端口号 进行网络版本的进程间通信
但客户端是不需要自己绑定的,由操作系统自动进行绑定
如:电脑和手机充满大量客户端,这些客户端来自于不同的企业,每个客户端的端口号不可以是固定的
必须让操作系统随机去选择,本质是为了防止确定的客户端被别人去占用,减少客户端层面的冲突
所以客户端的端口号要让操作系统随机分配,防止客户端出现启动冲突

服务器为什么要自己绑定?

1.服务器的端口 是 众所周知并不能随意改变的
如:110是报警电话,不可能报警电话每天都变,否则会导致当真正想打电话时都不知道打那个

2.服务器都是一家公司的,所以端口号需要统一规范化
如:淘宝不会把自己的服务部署到知乎上


代码实现

进行while循环,向服务器发送消息

目前没有消息,所以让用户输入充当消息源
使用 sendto,将消息发送给服务端

作为客户端将消息发送给 服务器主机
想要运行 客户端 ,就需要服务器的IP 和端口号


在这里插入图片描述
借助命令行参数,通过用户的输入的第二个参数 作为服务器的IP
用户输入的第三个作为 服务器的端口号

虽然此时服务器的IP和端口号知道了,但是想要借助sendto,后两个参数是需要套接字结构体


新建一个结构体server,内部包含服务器的IP和端口号
使用 htons ,将主机序列转为网络序列
使用inet_addr,将字符串转化为 4字节


在这里插入图片描述

此时 sendto的后两个参数 添加 创建的结构体 sever ,来完成发送服务器的任务
由于server 的类型 是 struct sockaddr_in ,而参数的类型为 公共结构体类型 struct sockaddr ,所以需要强转


使用 revfrom ,获取用户数据报
收到来自服务器转回来的消息 ,所以 定义一个 temp结构体,用于接收

在首次系统调用发送数据的时候,操作系统在底层随机选择客户端的端口号 加上自己的IP
先构建bind,再构建发送的数据报文

完整代码

err.hpp (枚举错误码)

#pragma onceenum 
{USAGE_ERR=1,SOCKET_ERR,BIND_ERR
};

makefile

.PHONY:all
all: udp_client udp_serverudp_client:udp_client.ccg++ -o  $@ $^ -std=c++11
udp_server:udp_server.ccg++ -o $@  $^ -std=c++11.PHONY:clean
clean:rm -f udp_clinet udp_server

udp_client.cc(客户端的实现,无封装)

#include"udp_client.hpp"
#include"err.hpp"
#include<cstring>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>static void usage(std::string proc)
{std::cout<<"usage:\n\t"<<proc<<"serverip serverport\n"<< std::endl;
}
// ./udp_client serverip sevrerport
int main(int argc ,char* argv[])//命令行参数 传入的是 客户端的运行 服务器的IP和端口号
{if(argc!=3){std::cout<<" "<<std::endl;exit( USAGE_ERR);//终止程序}std::string serverip = argv[1];//服务器的IPuint16_t serverport =atoi(argv[2]);//服务器的端口号int sock=socket(AF_INET,SOCK_DGRAM,0);if(sock<0)//创建套接字失败{std::cout<<"create socket error"<<std::endl;exit( SOCKET_ERR);}//明确server是谁struct sockaddr_in server;//设置网络通信的结构体memset(&server,0,sizeof(server)); //将结构体清空server.sin_family=AF_INET;server.sin_port=htons(serverport);//端口号server.sin_addr.s_addr=inet_addr(serverip.c_str());//IP地址while(true){//用户输入  std::string message;std::cout<<  "please enter# ";std::cin>> message;//发送消息sendto(sock,message.c_str(),message.size(),0,(struct sockaddr*)&server,sizeof(server));//接收消息char buffer[1024];struct sockaddr_in temp;socklen_t len=sizeof(temp);int n=recvfrom(sock,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&temp,&len);if(n>0){buffer[n]=0;//收到回显消息std::cout<<"server echo"<<buffer<<std::endl;}}return 0;
}

udp_clinet.hpp

#pragma once
#include<iostream>
using namespace std;

udp_server.cc (有封装)

#include"udp_server.hpp"
#include"err.hpp"
#include<memory>
#include<string>
using namespace ns_server;
using namespace std;static void usage(string proc)
{std::cout<<"usage:\n\t"<<proc<<"prot\n"<< std::endl;
}//udp_server port
int main(int argc,char*argv[])//命令行参数
{if(argc!=2)//若命令行参数个数不为2,则当前会报错{usage(argv[0]);exit(USAGE_ERR);//终止程序}//端口号uint16_t port=atoi(argv[1]);//atoi可将字符串转化为整数//只需传入由用户指明的端口号unique_ptr<UdpServer> usvr(new UdpServer (port));usvr->Initserver();//服务器的初始化usvr->Start();//启动服务器return 0;
}

udp_server.hpp(服务器的实现)

#pragma once
#include<iostream>
#include<cerrno>
#include<cstring>
#include<cstdlib> 
#include<strings.h>
#include<functional>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include"err.hpp"namespace  ns_server
{const static uint16_t  default_port=8082;//设置端口号为8082 class UdpServer{public:UdpServer(uint16_t port=default_port)//构造:port_(port){}void  Initserver()//初始化{//1.创建套接字接口,打开网络文件sock_=socket(AF_INET,SOCK_DGRAM,0);if(sock_<0)//创建失败{//打印错误信息std::cout<<" create socket   error: "<<strerror(errno)<<std::endl;exit(SOCKET_ERR);//终止程序}std::cout<<"create socket success:"<<sock_<<std::endl;//3//2.给服务器指明IP地址和端口号struct sockaddr_in local;bzero(&local,sizeof(local));//全部置为0local.sin_family=AF_INET;//将16位地址类型 置为 网络通信local.sin_port=  htons(port_); //主机转网络的端口号//1.需要将字符串风格转化为 4字节//2.需要 将主机序列转换为 网络序列local.sin_addr.s_addr= INADDR_ANY ; //bind本机上的任意IP//bind 绑定int n=bind(sock_,(struct sockaddr*)&local,sizeof(local));if(n<0)//绑定失败{std::cout<<" bind  socket   error: "<<strerror(errno)<<std::endl;exit(BIND_ERR);}std::cout<<"bind socket success:"<<sock_<<std::endl;//3}void Start()//启动{char buffer[1024];//用于保护用户数据//设置一个死循环while(true){//1.收到客户端发来的消息struct sockaddr_in peer;socklen_t len=sizeof(peer);//传入的缓冲区大小int n=recvfrom(sock_,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);if(n>0){buffer[n]='\0';}else {//读取失败,则继续读取continue;}//提取客户端信息//4字节IP转为 字符串IPstd::string clientip =inet_ntoa(peer.sin_addr);//客户端IP//将网络序列转换为主机序列uint16_t clientport =ntohs(peer.sin_port);//客户端 端口号std::cout<<clientip<<"-"<<clientport<<"-"<<"get message# "<<buffer<<std::endl;//2.将消息发给别人sendto(sock_,buffer,strlen(buffer),0,(struct sockaddr*)&peer,sizeof(peer));}}~UdpServer()//析构{}private:int sock_; //文件描述符uint16_t port_;//端口号 }; 
}

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

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

相关文章

[webpack] 基本配置 (一)

文章目录 1.基本介绍2.功能介绍3.简单使用3.1 文件目录和内容3.2 下载依赖3.3 启动webpack 4.基本配置4.1 五大核心概念4.2 基本使用 1.基本介绍 Webpack 是一个静态资源打包工具。它会以一个或多个文件作为打包的入口, 将我们整个项目所有文件编译组合成一个或多个文件输出出去…

webpack基础知识八:说说如何借助webpack来优化前端性能?

一、背景 随着前端的项目逐渐扩大&#xff0c;必然会带来的一个问题就是性能 尤其在大型复杂的项目中&#xff0c;前端业务可能因为一个小小的数据依赖&#xff0c;导致整个页面卡顿甚至奔溃 一般项目在完成后&#xff0c;会通过webpack进行打包&#xff0c;利用webpack对前…

医疗器械研发中的可用性工程实践(一)

致读者&#xff1a;以前看《楚门的世界》&#xff0c;《蝴蝶效应》&#xff0c;《肖申克的救赎》&#xff0c;《教父》&#xff0c;《横道世之介》&#xff0c;《老友记》&#xff0c;一个人的一生匆匆。作为平凡人就是历史大河中的浪花&#xff0c;顺势而为&#xff0c;起起伏…

算法与数据结构(二十一)二叉树(纲领篇)

备注&#xff1a;本文旨在通过 labuladong 的二叉树&#xff08;纲领篇&#xff09;理解框架思维&#xff0c;用于个人笔记及交流学习&#xff0c;版权归原作者 labuladong 所有&#xff1b; 我刷了这么多年题&#xff0c;浓缩出二叉树算法的一个总纲放在这里&#xff0c;也许…

ELK企业级日志分析系统

目录 一、ELK 概述 1.ElasticSearch 2.Kiabana 3.Logstash 可以添加的其它组件 1.Filebeat 2.Fluentd 三、为什么要使用 ELK 四、ELK 的工作原理 五、 ELK Elasticsearch 集群部署 更改主机名、配置域名解析、查看Java环境 部署 Elasticsearch 软件 修改elasticsearc…

爬虫获取电影数据----以沈腾参演电影为例

数据可视化&分析实战 1.1 沈腾参演电影数据获取 文章目录 数据可视化&分析实战前言1. 网页分析2. 构建数据获取函数2.1 网页数据获取函数2.2 网页照片获取函数 3. 获取参演影视作品基本数据4. 电影详细数据获取4.1 导演、演员、描述、类型、投票人数、评分信息、电影海…

Wisej.NET Crack,Wisej.NET的核心功能

Wisej.NET Crack&#xff0c;Wisej.NET的核心功能 Wisej.NET是一个跨平台的web框架&#xff0c;用于使用.NET和C#/VB.NET而不是HTML和JavaScript构建现代HTML5应用程序。它包含创建任务关键型web应用程序所需的一切&#xff0c;包括UI组件、会话处理、状态管理和后端集成。借助…

单元测试之 - Spring框架提供的单元/集成测试注解

Spring框架提供了很多注解来辅助完成单元测试和集成测试(备注&#xff1a;这里的集成测试指容器内部的集成测试&#xff0c;非系统间的集成测试)&#xff0c;先看看Spring框架提供了哪些注解以及对应的作用。RunWith(SpringRunner.class) / ExtendWith(SpringExtension.class)&…

设计模式行为型——备忘录模式

目录 什么是备忘录模式 备忘录模式的实现 备忘录模式角色 备忘录模式类图 备忘录模式举例 备忘录模式代码实现 备忘录模式的特点 优点 缺点 使用场景 注意事项 实际应用 什么是备忘录模式 备忘录模式&#xff08;Memento Pattern&#xff09;又叫做快照模式&#x…

高并发负载均衡---LVS

目录 前言 一&#xff1a;负载均衡概述 二&#xff1a;为啥负载均衡服务器这么快呢&#xff1f; ​编辑 2.1 七层应用程序慢的原因 2.2 四层负载均衡器LVS快的原因 三&#xff1a;LVS负载均衡器的三种模式 3.1 NAT模式 3.1.1 什么是NAT模式 3.1.2 NAT模式实现LVS的缺点…

openwr折腾记7-Frpc使用自主域名解析透传本地服务免费不断线的探索

Frpc使用自主域名解析透传本地服务 综述frp透传http服务结构流程 第一部分openwrt-frpc客户端配置和使用指定服务器指定规则在自己的域名运营商处添加域名解析 第二部分shell编码实现frp自由切换服务器并更新dns解析获取切换服务器参数脚本实现切换脚本更新DNS解析打开openwrt计…

MySQL — InnoDB事务

文章目录 事务定义事务特性事务隔离级别READ UNCOMMITTEDREPEATABLE READREAD COMMITTEDSERIALIZABLE 事务存在的问题脏读&#xff08;Dirty Read&#xff09;不可重复读&#xff08;Non-repeatable Read&#xff09;幻读&#xff08;Phantom Read&#xff09; 事务定义 数据库…

(十三)大数据实战——hadoop集群之YARN高可用实现自动故障转移

前言 本节内容是关于hadoop集群下yarn服务的高可用搭建&#xff0c;以及其发生故障转移的处理&#xff0c;同样需要依赖zookeeper集群的实现&#xff0c;实现该集群搭建时&#xff0c;我们要预先保证zookeeper集群是启动状态。yarn的高可用同样依赖zookeeper的临时节点及监控&…

构建器/建造者/构建者模式(C++)

定义 将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)。 应用场景 在软件系统中&#xff0c;有时候面临着“一个复杂对象”的创建工作&#xff0c;其通常由各个部分的子对象用一定的算法构成;由于需求的变化&#xff0c;这个复杂对象…

Android应用开发(6)TextView进阶用法

Android应用开发学习笔记——目录索引 上一章Android应用开发&#xff08;5&#xff09;文本视图&#xff08;TextView&#xff09;介绍了文本视图&#xff08;TextView&#xff09;设置文本内容、设置文本大小、设置文本显示颜色。 TextView是最基础的文本显示控件&#xff…

PHP正则绕过解析

正则绕过 正则表达式PHP正则回溯PHP中的NULL和false回溯案例案例1案例2 正则表达式 在正则中有许多特殊的字符&#xff0c;不能直接使用&#xff0c;需要使用转义符\。如&#xff1a;$,(,),*,,.,?,[,,^,{。 这里大家会有疑问&#xff1a;为啥小括号(),这个就需要两个来转义&a…

Linux 下设置开机自启动的方法

文章目录 事先准备对于普通的 Linux对于 RedHat Enterprise Linux 9 笔者的运行环境&#xff1a; 设置成功过的 Linux&#xff1a; RedHat Enterprise Linux 9 x86_64 CentOS 8 x86_64 事先准备 进行这个教程之前&#xff0c;必须要先安装好一个 Linux 操作系统。这个 Linux…

JavaWeb 手写Tomcat底层机制

目录 一、Tomcat底层整体架构 1.简介 : 2.分析图 : 3.基于Socket开发服务端的流程 : 4.打通服务器端和客户端的数据通道 : 二、多线程模型的实现 1.思路分析 : 2.处理HTTP请求 : 3.自定义Tomcat : 三、自定义Servlet规范 1. HTTP请求和响应 : 1 CyanServletRequest …

《面试1v1》ElasticSearch基础

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

Kafka的配置和使用

目录 1.服务器用docker安装kafka 2.springboot集成kafka实现生产者和消费者 1.服务器用docker安装kafka ①、安装docker&#xff08;docker类似于linux的软件商店&#xff0c;下载所有应用都能从docker去下载&#xff09; a、自动安装 curl -fsSL https://get.docker.com | b…