PL0编译器TurboPascal版再现时间:2009-07-20 17:24:49来源:网络 作者:未知 点击:52次
(********************* PL0 编译程序Turbo Pascal代码 *********************)
(********************* PL0 编译程序Turbo Pascal代码 *********************)
program pl0(fa,fa1,fa2);
(* PL0 compile with code generation *)
label 99;
(* Turbo Pascal do not support goto between different
blocks so, the 'goto' command in getch are replaced
by procedure exitp !! in another way, 'label 99' do
not work !! Lin Wei 2001 *)
const norw=13; (* of reserved words *)
txmax=100; (* length of identifier table *)
nmax=14; (* max number of digits in numbers *)
al=10; (* length of identifiers *)
amax=2047; (* maximum address *)
levmax=3; (* max depth of block nesting *)
cxmax=200; (* size of code array *)
type symbol=(nul,ident,number,plus,minus,times,slash,oddsym,
eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,
semicolon,period,becomes,beginsym,endsym,ifsym,
thensym,whilesym,writesym,readsym,dosym,callsym,
constsym,varsym,procsym);
alfa=packed array[1..al] of char;
objects=(constant,variable,procedur);
(* wirth used the word "procedure"and"object" there, which won't work! *)
symset=set of symbol;
fct=(lit,opr,lod,sto,cal,int,jmp,jpc);
instruction=packed record
f:fct; (* function code *)
l:0..levmax; (* level *)
a:0..amax; (* displacement addr *)
end;
(* lit 0,a load constant a
opr 0,a execute opr a
lod 1,a load variable 1,a
sto 1,a store variable 1,a
cal 1,a call procedure at level 1
int 0,a increment t -register by a
jmp 0,a jump to a
jpc 0,a jump conditional to a *)
var fa:text;
fa1,fa2:text;
listswitch:boolean; (* true set list object code *)
ch:char; (* last char read *)
sym:symbol; (* last symbol read *)
id:alfa; (* last identifier read *)
num:integer; (* last number read *)
cc:integer; (* character count *)
ll:integer; (* line length *)
kk:integer;
cx:integer; (* code allocation index *)
line:array[1..81] of char;
a:alfa;
code:array[0..cxmax] of instruction;
word:array[1..norw] of alfa;
wsym:array[1..norw] of symbol;
ssym:array[' '..'^'] of symbol;
(* wirth uses "array[char]" here *)
mnemonic:array[fct] of packed array[1..5] of char;
declbegsys, statbegsys, facbegsys:symset;
table:array[0..txmax] of record
name:alfa;
case kind:objects of
constant:(val:integer);
variable,procedur:(level,adr,size:integer)
(* "size" lacking in original. I think it belongs here *)
end;
fin,fout:text;
fname:string;
err:integer;
endf:boolean;
procedure error(n:integer);
begin
writeln('****','':cc-1,'!',n:2);
writeln(fa1,'****','':cc-1,'!',n:2);
err:=err+1;
end; (* error *)
procedure exitp;
begin
endf:=true;
close(fin);
writeln;
exit;
end;
procedure getsym;
var i,j,k:integer;
procedure getch;
begin
if cc=ll then begin
if eof(fin) then begin
write('program incomplete');
close(fin);
writeln;
exitp;
(*goto 99;*)
end;
ll:=0;
cc:=0;
write(cx:4,' ');
write(fa1,cx:4,' ');
while not eoln(fin) do begin
ll:=ll+1;
read(fin,ch);
write(ch);
write(fa1,ch);
line[ll]:=ch;
end;
writeln;
ll:=ll+1;
(* read(fin,line[ll]); repleaced by two lines below *)
line[ll]:=' ';
readln(fin);
writeln(fa1);
end;
cc:=cc+1;
ch:=line[cc];
end; (* getch *)
begin (* getsym *)
while ch=' ' do getch;
if ch in ['a'..'z'] then begin
k:=0;
repeat
if k<al then begin
k:=k+1;
a[k]:=ch;
end;
getch;
until not(ch in ['a'..'z','0'..'9']);
if k>=kk then kk:=k
else repeat
a[kk]:=' ';
kk:=kk-1;
until kk=k;
id:=a;
i:=1;
j:=norw;
repeat
k:=(i+j) div 2;
if id<=word[k] then j:=k-1;
if id>=word[k] then i:=k+1;
until i>j;
if i-1>j then sym:=wsym[k] else sym:=ident;
end else if ch in ['0'..'9'] then begin (* number *)
k:=0;
num:=0;
sym:=number;
repeat
num:=10*num+(ord(ch)-ord('0'));
k:=k+1;
getch;
until not(ch in['0'..'9']);
if k>nmax then error(30);
end else if ch=':' then begin
getch;
if ch='=' then begin
sym:=becomes;
getch;
end else sym:=nul;
end else if ch='<' then begin
getch;
if ch='=' then begin
sym:=leq;
getch;
end else sym:=lss;
end else if ch='>' then begin
getch;
if ch='=' then begin
sym:=geq;
getch;
end else sym:=gtr;
end else begin
sym:=ssym[ch];
getch;
end;
end; (* getsym *)
procedure gen(x:fct;y,z:integer);
begin
if cx>cxmax then begin
write('program too long');
(*goto 99;*)
end;
with code[cx] do begin
f:=x;
l:=y;
a:=z;
end;
cx:=cx+1;
end; (* gen *)
procedure test(s1,s2:symset;n:integer);
begin
if not(sym in s1) then begin
error(n);
s1:=s1+s2;
while not(sym in s1) do getsym;
end;
end; (* test *)
procedure block(lev,tx:integer;fsys:symset);
var dx:integer; (* data allocation index *)
tx0:integer; (* inital table index *)
cx0:integer; (* inital code index *)
procedure enter(k:objects);
begin (* enter object into table *)
tx:=tx+1;
with table[tx] do begin
name:=id;
kind:=k;
case k of
constant: begin
if num>amax then begin error(31); num:=0; end;
val:=num;
end;
variable: begin
level:=lev;
adr:=dx;
dx:=dx+1;
end;
procedur: level:=lev;
end;
end;
end; (* enter *)
function position(id:alfa):integer;
var i:integer;
begin (* find identifier in table *)
table[0].name:=id;
i:=tx;
while table[i].name<>id do i:=i-1;
position:=i;
end; (* position *)
procedure constdeclaration;
begin
if sym=ident then begin
getsym;
if sym in [eql,becomes] then begin
if sym=becomes then error(1);
getsym;
if sym=number then begin
enter(constant);
getsym;
end else error(2);
end else error(3);
end else error(4);
end; (* constdeclaration *)
procedure vardeclaration;
begin
if sym=ident then begin
enter(variable);
getsym;
end else error(4);
end; (* vardeclaration *)
procedure listcode;
var i:integer;
begin
if listswitch then begin
for i:=cx0 to cx-1 do
with code[i] do begin
writeln(i,mnemonic[f]:5,l:3,a:5);
writeln(fa,i:4,mnemonic[f]:5,l:3,a:5);
end;
end;
end; (* listcode *)
procedure statement(fsys:symset);
var i,cx1,cx2:integer;
procedure expression(fsys:symset);
var addop:symbol;
procedure term(fsys:symset);
var mulop:symbol;
procedure factor(fsys:symset);
var i:integer;
begin
test(facbegsys,fsys,24);
while sym in facbegsys do begin
if sym=ident then begin
i:=position(id);
if i=0 then error(11)
else with table[i] do
case kind of
constant:gen(lit,0,val);
variable:gen(lod,lev-level,adr);
procedur:error(21);
end;
getsym;
end else if sym=number then begin
if num>amax then begin
error(31);
num:=0;
end;
gen(lit,0,num);
getsym;
end else if sym=lparen then begin
getsym;
expression([rparen]+fsys);
if sym=rparen then getsym
else error(22);
end;
test(fsys,facbegsys,23);
end;
end; (* factor *)
begin (* term *)
factor([times,slash]+fsys);
while sym in [times,slash] do begin
mulop:=sym;
getsym;
factor(fsys+[times,slash]);
if mulop=times then gen(opr,0,4) else gen(opr,0,5)
end;
end; (* term *)
begin (* expression *)
if sym in [plus,minus] then begin
addop:=sym;
getsym;
term(fsys+[plus,minus]);
if addop=minus then gen(opr,0,1);
end else term(fsys+[plus,minus]);
while sym in [plus,minus] do begin
addop:=sym;
getsym;
term(fsys+[plus,minus]);
if addop=plus then gen(opr,0,2) else gen(opr,0,3);
end;
end; (* expression *)
procedure condition(fsys:symset);
var relop:symbol;
begin
if sym=oddsym then begin
getsym;
expression(fsys);
gen(opr,0,6);
end else begin
expression([eql,neq,lss,leq,gtr,geq]+fsys);
if not(sym in [eql,neq,lss,leq,gtr,geq]) then error(20)
else begin
relop:=sym;
getsym;
expression(fsys);
case relop of
eql:gen(opr,0,8);
neq:gen(opr,0,9);
lss:gen(opr,0,10);
geq:gen(opr,0,11);
gtr:gen(opr,0,12);
leq:gen(opr,0,13);
end;
end;
end;
end; (* condition *)
begin (* statement *)
if sym=ident then begin
i:=position(id);
if i=0 then error(11)
else if table[i].kind<>variable then begin
error(12);
i:=0;
end;
getsym;
if sym=becomes then getsym else error(13);
expression(fsys);
if i<>0 then with table[i] do gen(sto,lev-level,adr);
end else if sym=readsym then begin
getsym;
if sym<>lparen then error(34)
else repeat
getsym;
if sym=ident then i:=position(id)
else i:=0;
if i=0 then error(35)
else with table[i] do begin
gen(opr,0,16);
gen(sto,lev-level,adr);
end;
getsym;
until sym<>comma;
if sym<>rparen then begin
error(33);
while not(sym in fsys) do getsym;
end else getsym;
end else if sym=writesym then begin
getsym;
if sym=lparen then begin
repeat
getsym;
expression([rparen,comma]+fsys);
gen(opr,0,14);
until sym<>comma;
if sym<>rparen then error(33) else getsym;
end;
gen(opr,0,15);
end else if sym=callsym then begin
getsym;
if sym<>ident then error(14)
else begin
i:=position(id);
if i=0 then error(11) else with table[i] do
if kind=procedur then gen(cal,lev-level,adr)
else error(15);
getsym;
end;
end else if sym=ifsym then begin
getsym;
condition([thensym,dosym]+fsys);
if sym=thensym then getsym
else error(16);
cx1:=cx;
gen(jpc,0,0);
statement(fsys);
code[cx1].a:=cx;
end else if sym=beginsym then begin
getsym;
statement([semicolon,endsym]+fsys);
while sym in [semicolon]+statbegsys do begin
if sym=semicolon then getsym
else error(10);
statement([semicolon,endsym]+fsys);
end;
if sym=endsym then getsym else error(17);
end else if sym=whilesym then begin
cx1:=cx;
getsym;
condition([dosym]+fsys);
cx2:=cx;
gen(jpc,0,0);
if sym=dosym then getsym else error(18);
statement(fsys);
gen(jmp,0,cx1);
code[cx2].a:=cx;
end;
test(fsys,[],19);
end; (* statement *)
begin (* block *)
dx:=3;
tx0:=tx;
table[tx].adr:=cx;
gen(jmp,0,0);
if lev>levmax then error(32);
repeat
if sym=constsym then begin
getsym;
repeat
constdeclaration;
while sym=comma do begin
getsym;
constdeclaration;
end;
if sym=semicolon then getsym else error(5);
until sym<>ident;
end;
if sym=varsym then begin
getsym;
repeat;
vardeclaration;
while sym=comma do begin
getsym;
vardeclaration;
end;
if sym=semicolon then getsym else error(5);
until sym<>ident;
end;
while sym=procsym do begin
getsym;
if sym=ident then begin
enter(procedur);
getsym;
end else error(4);
if sym=semicolon then getsym else error(5);
block(lev+1,tx,[semicolon]+fsys);
if sym=semicolon then begin
getsym;
test(statbegsys+[ident,procsym],fsys,6);
end else error(5);
end;
test(statbegsys+[ident],declbegsys,7);
until not(sym in declbegsys);
code[table[tx0].adr].a:=cx;
with table[tx0] do begin
adr:=cx;
size:=dx;
end;
cx0:=cx;
gen(int,0,dx);
statement([semicolon,endsym]+fsys);
gen(opr,0,0);
test(fsys,[],8);
listcode;
end; (* block *)
procedure interpret;
const stacksize=500;
var p,b,t:integer; (* program base topstack registers *)
i:instruction;
s:array[1..stacksize] of integer; (* datastore *)
function base(l:integer):integer;
var bl:integer;
begin
bl:=b; (* find base 1 level down *)
while l>0 do begin
bl:=s[bl];
l:=l-1;
end;
base:=bl;
end; (* base *)
begin
writeln('start pl0');
t:=0; b:=1; p:=0;
s[1]:=0; s[2]:=0; s[3]:=0;
repeat
i:=code[p];
p:=p+1;
with i do case f of
lit: begin t:=t+1; s[t]:=a; end;
opr: case a of (* operator *)
0: begin (* return *)
t:=b-1;
p:=s[t+3];
b:=s[t+2];
end;
1: s[t]:=-s[t];
2: begin t:=t-1; s[t]:=s[t]+s[t+1]; end;
3: begin t:=t-1; s[t]:=s[t]-s[t+1]; end;
4: begin t:=t-1; s[t]:=s[t]*s[t+1]; end;
5: begin t:=t-1; s[t]:=s[t] div s[t+1]; end;
6: s[t]:=ord(odd(s[t]));
8: begin t:=t-1; s[t]:=ord(s[t]=s[t+1]); end;
9: begin t:=t-1; s[t]:=ord(s[t]<>s[t+1]); end;
10:begin t:=t-1; s[t]:=ord(s[t]<s[t+1]); end;
11:begin t:=t-1; s[t]:=ord(s[t]>=s[t+1]); end;
12:begin t:=t-1; s[t]:=ord(s[t]>s[t+1]); end;
13:begin t:=t-1; s[t]:=ord(s[t]<=s[t+1]); end;
14:begin write(s[t]); write(fa2,s[t]); t:=t-1; end;
15:begin writeln; writeln(fa2); end;
16:begin t:=t+1; write('?'); write(fa2,'?'); readln(s[t]);
writeln(fa2,s[t]); end;
end;
lod: begin t:=t+1; s[t]:=s[base(l)+a]; end;
sto: begin s[base(l)+a]:=s[t]; (* writeln(s[t]) *) t:=t-1; end;
cal: begin (* generat new block mark *) s[t+1]:=base(l); s[t+2]:=b;
s[t+3]:=p; b:=t+1; p:=a; end;
int: t:=t+a;
jmp: p:=a;
jpc: begin if s[t]=0 then p:=a; t:=t-1; end;
end; (* with, case *)
until p=0;
close(fa2);
end; (* interpret *)
begin (* main *)
for ch:=' ' to '!' do ssym[ch]:=nul;
(* changed bacause of different character set
note the typos below in the original where
the alfas were not given the correct space *)
word[1]:='begin '; word[2]:='call ';
word[3]:='const '; word[4]:='do ';
word[5]:='end '; word[6]:='if ';
word[7]:='odd '; word[8]:='procedure ';
word[9]:='read '; word[10]:='then ';
word[11]:='var '; word[12]:='while ';
word[13]:='write ';
wsym[1]:=beginsym; wsym[2]:=callsym;
wsym[3]:=constsym; wsym[4]:=dosym;
wsym[5]:=endsym; wsym[6]:=ifsym;
wsym[7]:=oddsym; wsym[8]:=procsym;
wsym[9]:=readsym; wsym[10]:=thensym;
wsym[11]:=varsym; wsym[12]:=whilesym;
wsym[13]:=writesym;
ssym['+']:=plus; ssym['-']:=minus;
ssym['*']:=times; ssym['/']:=slash;
ssym['(']:=lparen; ssym[')']:=rparen;
ssym['=']:=eql; ssym[',']:=comma;
ssym['.']:=period; ssym['#']:=neq;
ssym[';']:=semicolon;
mnemonic[lit]:='lit '; mnemonic[opr]:='opr ';
mnemonic[lod]:='lod '; mnemonic[sto]:='sto ';
mnemonic[cal]:='cal '; mnemonic[int]:='int ';
mnemonic[jmp]:='jmp '; mnemonic[jpc]:='jpc ';
declbegsys:=[constsym,varsym,procsym];
statbegsys:=[beginsym,callsym,ifsym,whilesym];
facbegsys:=[ident,number,lparen];
(* page(output) *)
endf:=false;
assign(fa1,'PL0.txt');
rewrite(fa1);
write('input file? ');
write(fa1,'input file?');
readln(fname);
writeln(fa1,fname);
(* openf(fin,fname,'r'); ==> *)
assign(fin,fname); reset(fin);
write('list object code ?');
readln(fname);
write(fa1,'list object code ?');
listswitch:=(fname[1]='y');
err:=0;
cc:=0; cx:=0; ll:=0;
ch:=' '; kk:=al;
getsym;
assign(fa,'PL0-1.txt');
assign(fa2,'PL0-2.txt');
rewrite(fa);
rewrite(fa2);
block(0,0,[period]+declbegsys+statbegsys);
close(fa);
close(fa1);
if sym<>period then error(9);
if err=0 then interpret else write('error in pl/0 program');
99: (* this line is not work in turbo pascal so replace by
procedure exitp: see the memo at the top *)
close(fin);
writeln;
end.
本篇文章来源于:开发学院 http://edu.codepub.com 原文链接:http://edu.codepub.com/2009/0720/10355.php
相关推荐
晶体管的 栅极gate 材料选用 多晶硅polysilicon,并采用 自对准工艺 self-aligned IC后端版图 【VLSI】
本文为了解决为什么要使用多晶硅作栅极触点的问题,先介绍了MOS管的工作原理是通过栅极上所加的电压控制漏极与源极之间电流,然后解释了栅极的材料为什么选用多晶硅,然后介绍了晶体管里栅极的自对准工艺(Self-Aligned Gate )。
PL/0编译器(java version)–Praser.java
1: package compiler; 2: 3: import java.io.IOException; 4: import java.util.BitSet; 5: 6: /** 7: * 语法分析器。 这是PL/0分析器中最重要的部分, 在语法分析的过程中嵌入了语法错误检查和目标代码生成。 8: * 9: * ...
folium离线地图实战:从下载到部署的完整指南
本文提供了一份完整的folium离线地图实战指南。针对网络不稳定或内网环境下的地图应用需求,详细讲解了如何下载离线地图瓦片数据,并通过两种核心方法(直接替换URL与创建TileLayer)将其集成到folium中。文章还涵盖了部署优化、边界处理及资源本地化等关键步骤,帮助你构建完全脱离网络依赖的交互式地图应用。
pl0源码(可在delphi7中运行)
{$Apptype console} program pl0(fa,fa1,fa2); (* PL/0编译程序与代码生成解释运行程序 *) (* PL/0 compiler with code generation *) label 99; (* 声明出错跳转标记 *) (* 在Turbo Pascal 7.0中已不允许跨过程的GOTO转移,因此后面的GOTO语句均被我去除了,因此这里的l
别再为下载速度发愁了!手把手教你给qBittorrent/Transmission添加最新可用Tracker(附2024年实测地址清单)
本文提供2024年BT下载加速实战指南,详细解析Tracker工作原理与速度瓶颈,手把手教你为qBittorrent/Transmission添加最新可用Tracker,并附实测地址清单。通过优化配置和精选Tracker列表,显著提升下载速度和稳定性,解决连接延迟和peer数量限制问题。
Honeywell EPKS 核心功能块组态与执行调度实战解析
本文深入解析Honeywell EPKS系统的核心功能块组态与执行调度技术,涵盖控制模块(CM)、顺序控制模块(SCM)和输入输出模块(IOM)的配置方法。通过实战案例分享执行顺序(ORDERINCM)和CEE执行周期的优化策略,帮助工程师提升工业自动化系统的控制精度和运行效率。
PL0编译器TurboPascal版再现
(********************* PL0 编译程序Turbo Pascal代码 *********************)program pl0(fa,fa1,fa2); (* PL0 compile with code generation *) label 99; (* Turbo Pascal do not support goto between differ
STM32C8T6实战:用PID算法搞定超级电容的10W无线恒功率充电(附代码避坑)
本文详细介绍了如何使用STM32C8T6和PID算法实现超级电容的10W无线恒功率充电。通过优化硬件设计、动态调整PID参数以及三重滤波技术,解决了超级电容充电过程中的功率尖峰和效率问题。附有代码示例和调试经验,帮助开发者快速实现高效稳定的无线充电方案。
PL0编译器分析与语法扩展
pl0 编译器扩展
欺诈文本分类微调(一):基座模型选型
通义千问Qwen2具有0.5B、1.5B、7B、72B等一系列参数大小不等的模型,我们需要做的是从大到小依次测试每个模型的能力,找到满足自己需要的最小参数模型。依1.5B和1.5B-Instruct的主要区别:按照官方文档,前者是预训练模型,后者是经过指令微调的模型。
iOS安全和逆向系列教程 第18篇:iOS应用脱壳技术详解与实战
iOS应用脱壳技术详解与实战 摘要: 本文深入剖析了iOS应用脱壳技术,首先解释了加壳(如FairPlay DRM)与脱壳的基本概念及必要性。通过otool命令可以检测应用的加密状态。文章详细介绍了三种主流脱壳工具:经典dumpdecrypted工具的使用方法、现代化Clutch工具的安装配置以及基于Frida的高级脱壳方案frida-ios-dump。针对特殊情况,还提供了使用LLDB手动dump内存的技术细节,包括查找基地址、计算dump范围和内存读取等操作。最后介绍了修复Mach-O文件头的Pytho
四路 CAN 转 4G 网关
SG‑CAN‑4G‑410 为**四路隔离 CAN 转 4G 工业网关**,把 CAN2.0A/B 报文封装成 TCP/UDP 报文,通过 4G 无线网络实现 CAN 总线远程监控、远程控制。四路 CAN 相互独立;以太网仅用于本地配置,不做业务数据传输;支持移动 / 联通 / 电信 4G 网络。
飞牛NAS新增虚拟机功能,如果使用虚拟机网卡直通安装ikuai软路由(如何解决OVS网桥绑定失败以及打开ovs后无法访问飞牛nas等问题)
飞牛NAS新增虚拟机功能,如果使用虚拟机网卡直通安装ikuai软路由
【计算机网络】断点续传是怎么做到的:从 Range 请求到分片上传的完整机制
断点续传在下载侧靠的是 HTTP 现成的 Range 协议,Content-Range 保证偏移对得上,If-Range 防止文件变更导致的错误拼接;上传侧没有标准,需要自己设计 init/part/complete 三段式交互,核心是让服务端记住“哪些块已经收下”,从而把失败粒度从整个文件降到单个分片。 这套机制可以迁移到任何长耗时操作的设计上。判断方法很简单:先问失败粒度是多少。如果一次操作失败就得从头再来,那它迟早会在生产环境里出问题——传输、批量导入、数据迁移、长事务,都是同一个道理。把大操作切成
锂电池充电器电路设计 里面有电路
锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。
visio安装包
Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。
汽车电子标定与测量的核心基石XCP协议
控制逻辑(算法)与标定参数(数据)。如果每次优化参数都要修改源码、重新编译并刷写Flash,整个研发周期的效率将趋近于零。标定(Calibration)技术正是为了解决这一痛点而生。它允许工程师在ECU运行过程中,动态观察内部变量(测量,Measurement),并在不中断运行的前提下实时修改控制变量(标定,Calibration)。在这一领域,XCP(Universal Measurement and Calibration Protocol,通用测量与标定协议)是公认的行业标准与核心基石。
蓝牙模块HM-10手册
蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。
Linux 服务器性能排查手册(2026):CPU、内存、磁盘IO、网络四大瓶颈定位
iptables 四表五链模型、firewalld zone 信任级别、云安全组与主机防火墙的关系与优先级,避坑改了防火墙把自己挡在服务器外面的翻车事故。
华为的C语言编程规范.pdf
华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。
SD-WAN 与传统企业组网方式有什么区别?六个维度分析技术差异与适用场景
SD-WAN 与传统组网区别,主要体现在网络管理模式、链路调度能力、可视化水平以及多站点扩展方式上。传统组网技术成熟、架构灵活,对于站点较少、业务简单、网络结构稳定的企业来说,仍然具有较高的实用价值。SD-WAN 则通过软件定义和集中化管理,为多站点网络管理、链路质量监测和业务流量调度提供了另一种技术实现方式。两者并不存在绝对的替代关系。在实际网络建设中,也可以根据不同业务和网络区域采用混合架构。
【Linux网络】TCP 服务器并发处理多客户端:从 fork 分发到双重 fork 彻底消灭僵尸进程
拆解 TCP 服务器并发演进链:fork 分发连接、SIGCHLD 循环回收僵尸、双重 fork 交孙进程给 init 收养,并给出模型选型与线上排错对照。
网口ps端--基础知识--调试(1)--deepseek
你现在卡住,是因为这每一层(硬件、驱动、lwIP 协议、IP 地址)中,只要有一层不对,网口就不通。物理层:看灯。灯亮说明线没问题,PHY 没死。MAC 驱动层:看串口打印。有没有打印出Link Speed?如果卡在自协商,说明你的 PHY 驱动还没配好。lwIP 协议层:如果底层通了,IP 也配对了,你调用udp_recv注册了回调函数,当电脑发来 UDP 包时,lwIP 会自动把数据包拆开,送到你的回调函数里。你之前一直在改,就是一直在死磕第 1 层和第 2 层。
Windows syslog日志服务器搭建与模拟器对接
二 HCL 华三模拟器连接HOST直接让路由器接口UP。1.下载visualsyslog 日志服务器软件。4.7 日志服务器可以看到年份为2026年。2.2 华三路由器配置并执行日志服务器。2.4 华三路由器可以与日志服务器互通。3.2 日志服务器可以实时查看日志。3.4 日志服务器可以实时看到日志。4.6 路由器配置日志显示年份。五 日志服务器查看日志存放位置。4.5 日志服务器查看到日志。2.3 华三路由器接口UP。4.3 日志服务器清掉日志。路由器本地日志显示年份成功。4.在桌面生成快捷方式。
HTTP、SSE、WebSocket、Socket.IO:实时通信方案深度对比与选型指南
HTTP 是基础,是整个 Web 的底座;SSE 是单向推送的轻量最优解;WebSocket 是高性能双向实时通信的底层标准;Socket.IO 是一套降低开发门槛、抹平环境差异的上层框架。技术选型永远不是“哪个技术更酷”,而是匹配业务的实时性、交互方向、网络环境、团队维护成本。简单需求优先轻方案,复杂双向实时再上 WebSocket;如果追求快速落地、兼容各种奇葩网络,Socket.IO 是很好的选择。
计算机毕业论文系统测试怎么写:从测试用例设计到对比实验,让“工作量“看得见
本文系统阐述计算机毕业论文中“系统测试”章节的撰写方法,涵盖功能测试用例设计(等价类、边界值、判定表)、性能测试压测方案与关键指标(平均响应时间、P99、吞吐量)、对比实验设计原则及评价指标选取。强调通过量化数据、阶梯加压曲线、瓶颈定位与多维度对比,真实展现研究工作量与技术深度,提供可直接套用的测试用例表与实验方案模板,助力论文脱颖而出。
Linux网络编程:TCP多线程远程命令执行与线程池改造
前面已经实现了 TCP Echo Server,并且通过多进程和多线程解决了多个客户端连接的问题。不过目前服务器的业务还是比较简单,客户端发送什么,服务器就返回什么。这次在原来的多线程服务器上继续做一些改动,实现一个简单的远程命令执行功能。这次主要学习了两个内容。第一个是多线程远程命令执行。通过 Command 类封装命令的接收、检查、执行和结果返回,并使用 set 对允许执行的命令进行限制。第二个是线程池版本的 TCP Echo Server。通过和std::bind。
物联网通信协议全景梳理
本文系统梳理物联网通信协议体系,按分层架构(接入、网络、传输、应用层)解析主流协议特性与选型逻辑。核心观点:接入层决定连接方式,应用层决定数据交互模式,两者可灵活组合。关键建议:资源受限用CoAP+BLE/Zigbee;大规模云接入选MQTT+WiFi/NB-IoT;长距离低功耗用LoRa/NB-IoT;智能家居优先Matter over Thread/WiFi;实时交互用WebSocket;安全通信优选DTLS/QUIC。最终实现“按需选型,协同高效”的物联网通信设计。
python如何编通讯程序
通讯程序需要处理IP地址和端口。IP地址用于标识网络上的设备,端口用于标识设备上的服务。编写通讯程序时,需要选择合适的端口号并确保它不与其他服务冲突。此外
五个压测工具简介
本文对比五款主流性能测试工具:JMeter(开源全能,适合接口与复杂业务压测)、sysbench(数据库基准调优标杆,轻量高效)、ab(极简HTTP压测,快速摸底)、LoadRunner(商业企业级,支持复杂场景与特殊协议)、mysqlslap(MySQL内置,快速验证并发能力)。各具优势,适用于不同场景,开发者可根据需求选择。
1万+



被折叠的 条评论
为什么被折叠?



