【C语言】百行代码实现—俄罗斯方块

article/2025/10/29 21:01:52

文章目录

  • 自述
  • 整体框架和流程
    • 开始游戏页面设计
    • 游戏设计流程介绍
  • 注意
  • 可执行源码-全部

自述

这个代码是19年的末尾写的,最近就想着想把这个用博客分享出来,一方面是为了巩固自己的知识,另一方面也希望同学们能够因为这篇文章有所收获,所以也在原来代码的基础上添加了蛮多注释的(感觉就和重新写了一遍俄罗斯方块似的😂) ,如果对于这篇文章有任何问题都可以提出来,也希望这篇文章能够帮助到大家,谢谢大家。

整体框架和流程

开始游戏页面设计

欢迎界面
在这里插入图片描述
游戏开始界面
在这里插入图片描述
这些大家应该都可以知道这个页面的布局了吧,接下来我们来了解对于这些布局我们应该要利用哪些函数来设置


初始化画布
如果我们像要进行图形界面的编程和绘画的话就一定要去初始化画布

	//初始画布initgraph(550,660);//表示初始化长和宽

设置窗口标题:利用window接口

	//设置窗口标题:利用window接口HWND hwnd=GetHWnd();//hwnd变量来接收,句柄SetWindowText(hwnd,_T("俄罗斯方块  宋同学2019.12.18"));

对于显示中间的文字

	//设置文本的字体样式setfont(40,0,_T("微软雅黑"));//高度40个像素宽度自己适应setcolor(WHITE);outtextxy(205,200,_T("俄罗斯方块"));//利用坐标setfont(22,0,_T("楷体"));outtextxy(175,300,_T("编程从俄罗斯方块开始!"));Sleep(3000);//休眠3秒钟那样转到游戏界面就不会突兀,让玩家有准备时间

对于欢迎界面所有的代码:

void welcome(){//初始画布initgraph(550,660);//设置窗口标题:利用window接口HWND hwnd=GetHWnd();//hwnd变量来接收,句柄,用于SetWindowText(hwnd,_T("俄罗斯方块  宋同学2019.12.18"));//设置文本的字体样式setfont(40,0,_T("微软雅黑"));//高度40个像素宽度自己适应setcolor(WHITE);outtextxy(205,200,_T("俄罗斯方块"));setfont(22,0,_T("楷体"));outtextxy(175,300,_T("编程从俄罗斯方块开始!"));Sleep(3000);//休眠3秒钟那样转到游戏界面就不会突兀,让玩家有准备时间}

初始化游戏界面
有些变量是设置为全局变量所以先不要太在意,等会儿都会有源码分享出来

//初始化游戏界面
void initGameScene(){char str[16];cleardevice();//绘制长方形框rectangle(27,27,336,635);rectangle(29,29,334,633);rectangle(370,50,515,195);setfont(24,0,_T("楷体"));setcolor(LIGHTGRAY);outtextxy(405,215,_T("下一个"));setcolor(RED);outtextxy(405,280,_T("分数"));//score是分数,定义为全局变量,等会回有源码分享sprintf(str,"%d",score);//把score写入到str中转换为字符串形式outtextxy(415,310,str);//和分数的设置同理outtextxy(405,375,_T("等级"));sprintf(str,"%d",rank);outtextxy(415,405,str);//操作说明setcolor(LIGHTBLUE);outtextxy(390,475,_T("操作说明"));outtextxy(390,500,"↑:旋转");outtextxy(390,525,"↓:下降");outtextxy(390,550,"←:左移");outtextxy(390,575,"→:右移");outtextxy(390,600,"空格:暂停");}

由于代码量还是有一些的所以接下来就不每一个函数都进行分开讲,感觉那样那这篇博客就有点长了,后面有源码有挺多注释的,大家可以慢慢看。

游戏设计流程介绍

  • 设计图形界面
  • 更新"下一个"框框(利用随机取,当主窗口的图形落到最底下就更新(初始就直接先来一个))
  • 将下一个框框中的形态的图形复刻到主窗口的中
  • 实现主游戏窗口的方块进行移动
  • 进行消行处理
  • 更新分数以及等级

注意

其实这游戏设计起来其实不难,在我看来难点可能是出现在消行和更新方块的操作上,还有一点要注意的是,图形的更新可以通过先用黑方块把指定位置都给覆盖然后再重新画一个(这一点即适用于方块的下落也适用于下一个方块的更新上),对于消行的处理要注意的是:如果第i行的方块满了我们把这一行消了以后那么我们还要再次判断i行而不能直接判断i+1行,因为当我们第i行消了以后上面的方块压下来那么第i行可能还可以再消一次。


由于可能图形界面大家没怎么接触过所以我就单独的写了一下,其他的部分可能还是得靠大家自己的理解了,也没办法把所有的想法全部都写出来,下面的源码中加了蛮多的注释还是希望大家看看代码看看注释这样也能理解的深刻一些。

可执行源码-全部

头文件

#include<stdio.h>
#include<string>
#include<iostream>
#include<graphics.h>//图形界面编程
#include<time.h>
#include<conio.h>//kbhit()键盘捕捉的使用需要的头文件

各种宏定义及全局变量

#define BLOCK_COUNT 5
#define BlOCK_WIDTH 5
#define BLOCK_HEIGHT 5
#define UNIT_SIZE 20//右上角打印的方块的像素
#define START_X 130
#define START_Y 30
#define KEY_UP 72//向上按键ASCII码值为72
#define KEY_RIGHT 77
#define KEY_LEFT 75
#define KEY_DOWN 80
#define KEY_SPACE 32
int score=0;//分数
int rank=0;//等级int speed=500;
int minX=30;
int minY=30;//设置枚举值
typedef enum{BLOCK_UP,BLOCK_RIGHT,BLOCK_DOWN,BLOCK_LEFT}block_dir_t;typedef enum{MOVE_DOWN,MOVE_LEFT,MOVE_RIGHT
}move_dir_t;int NextIndex=-1;//下一个方块的种类
int BlockIndex=-1;//当前方块的种类int color[BLOCK_COUNT]={GREEN,CYAN,MAGENTA,BROWN,YELLOW
};int visit[30][15];int markcolor[30][15];//表示对应位置的方块的颜色//初始化各种方块,包括其形态变换
int block[BLOCK_COUNT*4][BlOCK_WIDTH][BLOCK_HEIGHT]={// | 形方块{ 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },// L 形方块{ 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },// 田 形方块{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },// T 形方块{ 0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 },// Z 形方块{ 0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 },
};//5种方块每种方块4种形态方块的表示是用5行5列来表示

各类方法

void welcome(){//初始画布initgraph(550,660);//设置窗口标题:利用window接口HWND hwnd=GetHWnd();//hwnd变量来接收SetWindowText(hwnd,_T("俄罗斯方块  宋同学2019.12.18"));//设置文本的字体样式setfont(40,0,_T("微软雅黑"));//高度40个像素宽度自己适应setcolor(WHITE);outtextxy(205,200,_T("俄罗斯方块"));setfont(22,0,_T("楷体"));outtextxy(175,300,_T("编程从俄罗斯方块开始!"));Sleep(3000);//休眠3秒钟那样转到游戏界面就不会突兀,让玩家有准备时间}
//初始化游戏界面
void initGameScene(){char str[16];cleardevice();rectangle(27,27,336,635);rectangle(29,29,334,633);rectangle(370,50,515,195);setfont(24,0,_T("楷体"));setcolor(LIGHTGRAY);outtextxy(405,215,_T("下一个"));setcolor(RED);outtextxy(405,280,_T("分数"));sprintf(str,"%d",score);outtextxy(415,310,str);outtextxy(405,375,_T("等级"));sprintf(str,"%d",rank);outtextxy(415,405,str);//操作说明setcolor(LIGHTBLUE);outtextxy(390,475,_T("操作说明"));outtextxy(390,500,"↑:旋转");outtextxy(390,525,"↓:下降");outtextxy(390,550,"←:左移");outtextxy(390,575,"→:右移");outtextxy(390,600,"空格:暂停");}
//清除右上角方块(用一个又一个的小黑方块把它遮住)
void clearBlock(){setcolor(BLACK);setfont(23,0,"楷体");//高度23for(int i=0;i<BLOCK_HEIGHT;i++){for(int j=0;j<BlOCK_WIDTH;j++){//"■"int x=391+UNIT_SIZE*j;int y=71+UNIT_SIZE*i;outtextxy(x,y, "■");	}}
}//在右上角区域绘制下一个方块
void drawBlock(int x,int y){setcolor(color[NextIndex]);setfont(23,0,"楷体");//高度23for(int i=0;i<BLOCK_HEIGHT;i++){for(int j=0;j<BlOCK_WIDTH;j++){//"■"if(block[NextIndex*4][i][j]==1){//对应哪一种方块(NextIndex*4)int x2=x+UNIT_SIZE*j;int y2=y+UNIT_SIZE*i;outtextxy(x2,y2, "■");	}}}}//绘制方块,特定位置特定方向的方块
void drawBlock(int x,int y,int blockIndex,block_dir_t dir){setcolor(color[NextIndex]);setfont(23,0,"楷体");//高度23,宽度自动适应int id=blockIndex*4+dir;for(int i=0;i<BLOCK_HEIGHT;i++){for(int j=0;j<BlOCK_WIDTH;j++){//"■"if(block[id][i][j]==1){//对应哪一种方块(NextIndex*4)int x2=x+UNIT_SIZE*j;int y2=y+UNIT_SIZE*i;outtextxy(x2,y2, "■");	}}}
}//下降过程中的清除方块的过程,一个一个的
//清除指定位置指定方向的方块
//参数x:方块的左上角的x坐标
//参数y:方块的左上角在游戏区域内的坐标,距离游戏区域顶部的距离
void clearBlock(int x,int y,block_dir_t dir){setcolor(BLACK);int id=BlockIndex*4+dir;y+=START_Y ;for(int i=0;i<5;i++){for(int j=0;j<5;j++){if(block[id][i][j]==1){ //擦除该方块的第i行第j列outtextxy(x+20*j,y+20*i,"■");}}}
}void nextblock(){clearBlock();//清除//随机选择一种方块srand(time(NULL));//使用时间函数的返回值来作为时间种子NextIndex=rand()%BLOCK_COUNT;drawBlock(391,71);//画方块(根据序号)
}//如果可以在指定位置可以向指定位置移动就返回1,否则返回0
int moveAble(int x0,int y0,move_dir_t moveDir,block_dir_t blockDir){//计算当前方块的左上角在30*15的游戏区域中的位置(多少行多少列)int x=(y0-minY)/UNIT_SIZE;//一个方块表示20像素int y=(x0-minX)/UNIT_SIZE;int id=BlockIndex*4+blockDir;//哪个方块哪种状态int ret=1;if(moveDir==MOVE_DOWN){for(int i=0;i<5;i++){for(int j=0;j<5;j++){if(block[id][i][j]==1&&(x+i+1>=30||visit[x+i+1][y+j]==1)){ret=0;}}}}else if(moveDir==MOVE_LEFT){for(int i=0;i<5;i++){for(int j=0;j<5;j++){if(block[id][i][j]==1&&(y+j==0||visit[x+i][y+j-1]==1)){ret=0;		}}}}else if(moveDir==MOVE_RIGHT){for(int i=0;i<5;i++){for(int j=0;j<5;j++){if(block[id][i][j]==1&&(y+j+1==15||visit[x+i][y+j+1]==1)){ret=0;		}}}}return ret;
}//检测函数是否结束
void failCheck(){//刚下来的时候都是向上的if(!moveAble(START_X,START_Y,MOVE_DOWN,BLOCK_UP)){setcolor(WHITE);setfont(45,0,"隶体");outtextxy(75,300,"GAME OVER!");Sleep(1000);system("pause");closegraph();exit(0);}
}//等待函数,这样比sleep函数好的地方是不会卡顿
void wait(int interval){int count=interval/10;for(int i=0;i<count;i++){Sleep(10);if(kbhit()){return;}}
}//很多时候可以利用反向思维去完成函数
//判断当前方块能否转向到指定方向
//注意此时还没开始转
int rotatable(int x,int y,block_dir_t Dir){int id=BlockIndex*4+Dir;int xIndex=(y-minY)/20;int yIndex=(x-minX)/20;if(!moveAble(x,y,MOVE_DOWN,Dir)){return 0;}for(int i=0;i<5;i++){for(int j=0;j<5;j++){if(block[id][i][j]==1&&(yIndex+j<0||yIndex+j>=15||visit[xIndex+i][yIndex+j]==1)){return 0;}}}return 1;
}//方块固定函数
void mark(int x,int y,int blockIndex,block_dir_t dir){int id=blockIndex*4+dir;int x2=(y-minX)/20;int y2=(x-minY)/20;for(int i=0;i<5;i++){for(int j=0;j<5;j++){if(block[id][i][j]==1){visit[x2+i][y2+j]=1;markcolor[x2+i][y2+j]=color[blockIndex];}}}}
//进行上下左右的移动
void move(){int x=START_X;int y=START_Y;int k=0;//偏移量block_dir_t blockDir=BLOCK_UP;int cur_speed=speed;//先检测游戏是否失败,再确认下降failCheck();//持续下降while(1){if(kbhit()){int key=getch();//和kbhit()组合使用if(key==KEY_SPACE){//碰到空格getch();//实现暂停}}//清除当前方块clearBlock(x,k,blockDir);//清除特定位置特定朝向的方块if(kbhit()){int key=getch();if(key==KEY_UP){/*********************变形*要求:要判断能不能翻转-》定义函数********************/block_dir_t nextDir=(block_dir_t)((blockDir+1)%4);if(rotatable(x,y+k,nextDir)){blockDir=nextDir;}}else if(key==KEY_DOWN){cur_speed=50;}else if(key==KEY_LEFT){if(moveAble(x,y+k+20,MOVE_LEFT,blockDir)){x-=UNIT_SIZE;}}else if(key==KEY_RIGHT){if(moveAble(x,y+k+20,MOVE_RIGHT,blockDir)){x+=UNIT_SIZE;}}}k+=20;//绘制当前方块drawBlock(x,y+k,BlockIndex,blockDir);wait(cur_speed);//利用sleep函数不太灵活容易出现卡顿所以就自己设计一个函数//方块的“固化”处理if(!moveAble(x,y+k,MOVE_DOWN,blockDir)){mark(x,y+k,BlockIndex,blockDir);//固定函数break;}}}void newblock(){//确定即将使用的方块的类别BlockIndex=NextIndex;//绘制刚从顶部下降的方块drawBlock(START_X,START_Y);//让新出现的方块停顿一会儿,让用户识别到Sleep(100);//0.1秒//右上角区域绘制下一个方块nextblock();//方块降落move();
}void down(int x){for(int i=x;i>0;i--){//清除第i行,第j列的方块消失for(int j=0;j<15;j++){if(visit[i-1][j]){visit[i][j]=1;markcolor[i][j]=markcolor[i-1][j];setcolor(markcolor[i][j]);outtextxy(20*j+minX,20*i+minY,"■");}else{visit[i][j]=0;setcolor(BLACK);outtextxy(20*j+minX,20*i+minY,"■");}}}//清除最上面行setcolor(BLACK);for(int j=0;j<15;j++){visit[0][j]=0;outtextxy(20*j+minX,minY,"■");}
}//更新分数
void addScore(int lines){char str[10];setcolor(RED);score+=lines*10;sprintf(str,"%d",score);outtextxy(415,310,str);
}//更新等级
void updateGrade(){//更新等级提示//50分隔一级char str[16];rank=score/50+1;sprintf(str,"%d",rank);outtextxy(425,405,str);//更新速度,自己可调整speed=500-rank*100;if(speed<=100){speed=100;}}//消行处理
void check(){int i;int j;int clearLines=0;for(i=29;i>=0;i--){//利用visit函数可以提高效率for(j=0;j<15&&visit[i][j];j++);//执行到此处时有两种情况//1.i行没满,此时j<15//2.i行满了,此时j>=15if(j>=15){//此时第i行已经满了//此时来消除第i行down(i);i++;//可能那一行可能还是可以消的所以再检测一遍clearLines++;}}//更新分数addScore(clearLines);//更新等级updateGrade();
}

主方法:

int main(){welcome();initGameScene();//产生新方块nextblock();Sleep(500);//初始化访问数组memset(visit,0,sizeof(visit));//从地址开始清为零大小为整个visit的数组大小while(1){newblock();//消除满行,并更新分数和等级check();}system("pause");closegraph();return 0;
}

http://chatgpt.dhexx.cn/article/mDgqRAyJ.shtml

相关文章

两张图片告诉你 载波聚合为4G加速的原因

描述 2015年被业界认为是LTE-A的规模商用元年&#xff0c;说到底&#xff0c;是载波聚合的规模商用。载波聚合作为LTE-A的关键技术之一&#xff0c;通过将两个或两个以上的载波&#xff08;Component Carrier&#xff0c;CC&#xff09;汇聚在一起&#xff0c;从而将分散的频谱…

LTE-A载波聚合技术(3)---L1/L2映射方案

1.5 L1/L2映射 1.5.1 NTT DOCOMO和Panasonic方案 DOCOMO和Panasonic提出的建议基本上是一样的&#xff0c;大体上可以分为3种&#xff1a; Option 1&#xff1a;每个CC一个TB和一个HARQ实体&#xff1b; Option 2&#xff1a;所有聚合的CC一个TB和一个HARQ实体&#xff1b; O…

LTE、NR载波聚合(CA)-- 等级划分

LTE、NR载波聚合(CA)-- 等级划分 一、LTE载波聚合等级划分:LTE根据载波对应的RB数命名 LTE CA信道参考3GPP TS 36.508 举个例子,“DC_3C-n78A”这个组合,就代表B3和n78这两个频段间的聚合,其中B3的频段内聚合等级为C,就表示2个LTE B3的带内聚合,且RB数量在100到200…

4G时代 载波聚合——用户、网络双受益

1、序言 2013下半年以来&#xff0c;载波聚合成为为先行LTE运营商网络演进的重点方向。进入2014年&#xff0c;随着爱立信与澳洲电讯宣布完成20MHz 20MHz载波聚合演示&#xff0c;韩国SK电信宣布年内商用20MHz 10MHz 10MHz三频段载波聚合&#xff0c;可以期待LTE商用网络的下…

[4G5G专题-12]:功能-LTE载波聚合CA对空口协议栈的影响概述

目录 1. LTE空口协议栈 2. 载波聚合对空口协议栈影响 2.1 载波聚合对空口协议栈影响的总体架构 2.2 L3 RRC层影响 2.3 L2 PDCP层影响 2.4 L2 RLC层影响 2.5 L2 MAC层影响 2.6 L1 PHY层影响 2.7 L0 Radio层影响 1. LTE空口协议栈 L0 RF: 负责模数转换、射频调制、无线…

【移动通信】4G载波聚合

载波聚合 Carrier Aggregation&#xff08;CA&#xff09; 根据香农定理&#xff0c;网速受限于带宽&#xff0c;载波聚合最早在3GPP R10版本提出。因为运营商的频谱比较碎&#xff0c;在低频段难以找到合适的大带宽&#xff0c;因此通过载波聚合将多个载波聚合成一个更宽的频…

4G+、VoLTE、载波聚合到底是啥?

原文地址&#xff1a;http://news.zol.com.cn/561/5613290.html 2016年来到了&#xff0c;运营商将普遍进入到4G时代&#xff0c;4G就是比4G还快的意思&#xff0c;下载速率可达300M。这个“”的帽子并不能乱戴&#xff0c;必须得应用了两个新技术才可称为4G&#xff0c;这两个…

基于MATLAB的LTEA载波聚合算法仿真

目录 一、理论基础 二、案例背景 1.问题描述 2.思路流程 三、部分MATLAB仿真 四、仿真结论分析 五、参考文献 一、理论基础 在非连续载波聚合( 高频低频) 场景下&#xff0c;载波衰减特性不同&#xff0c;聚合的载波有不同的覆盖范围&#xff0c;使得不同用户可调度的载…

LTE-A载波聚合技术(1)---载波聚合的技术特征、分类、仿真场景

1 技术特征 1.1 Carrier Aggregation概述 为了支持LTE-A达到100MHz的系统带宽的要求&#xff0c;3GPP在#53bis会议上提出了载波聚合。所谓载波聚合&#xff0c;就是LTE-A为了支持下行传输带宽超过20MHz聚合两个或者更多的成分载波&#xff08;component carrier&#xff09;。…

载波聚合CA

为什么需要载波聚合&#xff1f; 一般来说&#xff0c;要提升网速或者容量&#xff0c;有下面几个思路&#xff1a; 建更多的基站&#xff1a;这样一来同一个基站下抢资源的人就少了&#xff0c;网速自然就上去了。但缺点是投入太大了&#xff0c;运营商肯定不会做亏本的买卖…

CA(载波聚合)

文章目录 CA基本概念1. CA分类2. Pcell、Scell以及Serving CellPcell&#xff08;Primary Cell&#xff09;Scell&#xff08;Secondary Cell&#xff09; 3. Pcell、Scell部署场景场景1场景2场景3场景4 4. CA的协议控制4.1 Camping/Connetion Establishment:4.2 CC Management…

通俗说法+专业解释,载波聚合

通俗说法专业解释&#xff0c;载波聚合那些事全明白 发布时间&#xff1a;2016-05-19 13:36:30 来源&#xff1a;RF技术社区 (http://rf.eefocus.com) 标签&#xff1a;传输带宽载波聚合&#xff08;CA&#xff09;LTE频段 导读&#xff1a;随着LTE深入发展&#xff0c;用户…

载波聚合

一.为什么要进行载波聚合&#xff1f; lte中最大带宽是20M&#xff08;100个PRB&#xff09;,该小区下ue能获得速率是有限的&#xff08;LTE_FDD上行理想状态下75Mbps左右&#xff0c;而下行理想状态在175Mbps&#xff08;注&#xff1a;后面我会专门一篇文章计算LTE_TDD&#…

载波聚合(CA)

载波聚合(CA) 1. 载波聚合目的 为了满足LTE-A下行峰速1 Gbps&#xff0c;上行峰速500 Mbps的要求&#xff0c;需要提供最大100 MHz的传输带宽&#xff0c;但由于这么大带宽的连续频谱的稀缺&#xff0c;LTE-A提出了载波聚合&#xff08;Carrier Aggregation&#xff0c;CA&…

载波聚合(CA)-carrier aggregation

1 为什么需要载波聚合&#xff1f; 一般来说&#xff0c;要提升网速或者容量&#xff0c;有下面几个思路&#xff1a; 建更多的基站&#xff1a;这样一来同一个基站下抢资源的人就少了&#xff0c;网速自然就上去了。但缺点是投入太大了&#xff0c;运营商肯定不会做亏本的买…

到底什么是载波聚合(CA)?

1 为什么需要载波聚合&#xff1f; 一般来说&#xff0c;要提升网速或者容量&#xff0c;有下面几个思路&#xff1a; 建更多的基站&#xff1a;这样一来同一个基站下抢资源的人就少了&#xff0c;网速自然就上去了。但缺点是投入太大了&#xff0c;运营商肯定不会做亏本的买卖…

ntpdate同步时间出现:no server suitable for synchronization found 最终解决方案!

搭建zabbix服务器时&#xff0c;用ntpdate同步时间出错 ntpdate[2685]: no server suitable for synchronization found 百度查阅资料&#xff0c;尝试了以下数种方法&#xff1a; 换别的时间服务器 ping 域名得到IP&#xff0c;在linux和windows上都ping&#xff0c;根据得到…

内网安装ntpdate时间同步工具

查询是否安装NTP服务 # rpm -qa | grep ntp 根据系统版本寻找合适的RPM安装包。 RPM下载网站&#xff1a;​​https://pkgs.org/download/ntp​​(几乎涵盖了所有RPM包) 下载安装ntpdate wget http://mirror.centos.org/centos/7/os/x86_64/Packages/ntpdate-4.2.6p5-29.el7.ce…

CentOS服务器ntpdate同步及使用ntpdate同步时钟服务器时间

一、centos服务器ntpdate同步 如有多台CentOS服务器运行相同的服务&#xff0c;且对时间准确性要求较高&#xff0c;那必须保证多台服务器时间统一。 最简单的就是每台服务器都用ntpdate同步同一台网络时间服务器的时间。 1、输入ntpdate time.nist.gov同步网络时间 [rootl…

工业协议:DNP协议

一、 数据链路层规约 数据链路层规约文件规定了DNP3.0版的数据链路层&#xff0c;链路规约数据单元(LPDU)以及数据链路服务和传输规程。数据采用一种可变帧长格式&#xff1a;FT3。 FT3 帧长格式&#xff1a; 一个FT3帧被定义为一个固定长度的报头&#xff0c;随后是可以选用…