udp_chating(python) 项目下载地址:https://github.com/Abandon339/udp_chating#udp_chatingpython 说明:基于UDP socket的C/S模式下的简单多人聊天室 (Linux和windows都已兼容) 实现功能: 用户注册:要求服务器端在用户注册好账号后存储账号信息到数据库或者其他存储文件中。 用户登录:要求客户端基于UDP发送账号和密码给服务器,服务器端通过存储本地的账号信息与接收到的信息比较,匹配的话则登录成功,发回响应 公聊:要求客户端发送消息后,服务器能广播消息到所有在线的用户。 私聊:要求客户端指定目标好友发送消息,服务器能对应一个目标进行转发消息 python库介绍 Socket:套接字库,它提供了标准的 BSD Sockets API,可以访问底层操作系统 Socket 接口的全部方法。 mysql.connector:MySQL 官方提供的驱动器,用来连接使用Mysql。 time: 处理时间的标准库。time库能够表达计算机时间,提供获取系统时间并格式化输出的方法,提供系统级精确计时功能(....
[6]完善内核(内联汇编、c混编)
完善内核 1:函数调用约定 参数传递方式---------存放在栈中 在函数未执行前发生进程切换,参数还是需要转移阵地,寄存器又太少,干脆直接放在内存中 为了避免多进程的参数覆盖问题,将参数放在进程自己的栈中。 参数压栈顺序---------从右向左,栈空间的清理员----------调用者(仅限在当前cdecl调用约定下) 由于编写函数的程序员或者调用函数的人都知道需要调用的参数,所以这些工作其实有谁做都可以,只需要双方做好约定即可。调用约定例如有cdecl,syscall,optlink,thiscall cdecl ( C declaration,即 C 声明〉,起源于 C语言的一种调用约定,在c语言中,函数参数是 从右到左的顺序入梭的。 GNU/Linux GCC,把这一约定作为 准, x86 架构上的许多 C 编译器也都使用这个约定。在 cdecl 中,参数是在栈中传递的。 EAX、 ECX 和 EDX 寄存 器是由调用者保存的,其余的寄存器由被调用者保存.函数的返回值存储在 EAX 寄存器。 由 调用者清理栈空间 2:汇编、c混编 为何要混编: 汇编可以直接操作寄....
杭电操作系统实验三模拟shell
实验三:linux进程管理 1)实现一个模拟的shell 问题:编写三个cmd1.c、cmd2.c、cmd3.c程序,功能自定。需要一个仿shell的程序和实现类似执行grep、find等命令的程序。通过在仿shell中输入命令(字符串和参数),创建子进程来执行相应的命令程序,父进程需要等待子进程处理结束后,才能再去查看是否有新的命令。输入“exit”退出shell程序。输入无效命令则显示“Command not found”,等待下一个新命令。 前说下,刚开始把问题看复杂了,除了要求之外还写了cd、pwd、exit、mkdir,所以可以自行删改(不麻烦),或者有兴趣可以加更多的命令玩玩 : ) 处理方法: myshell.c: 提供循环输入命令模块 解析命令 判断命令是内置命令还是外置命令(可以不用) 内置命令直接调用函数,外置命令用fork()来创建一个子进程, 在进程中执行命令程序采用exec族的函数来调用函数执行。 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #in....
[7]了解中断的实现——逐步深入底层
中断 1:中断概述 并发和并行的区别: 单核cpu-并发:单位时间内的积累工作量,如在一秒内cpu处理了100个请求量 多核cpu-并行:真正同时进行的工作量,如在任意瞬间cpu正在同时处理100个请求量 系统有了中断,才能够并发运行,能够不断的切换进程。 操作系统是中断驱动的,本身是一个死循环while(1){ 操作系统代码 },所以系统是在循环中等待事件的发生,被动的调用资源去处理,而事件是由中断去通知系统的的。 2:中断类型 外部中断:由外部硬件发出的中断信号,再细分有可屏蔽中断和不可屏蔽中断 内部中断:内部发出,再细分有软中断和异常 补充:软中断int3断点调试指令,常用在GDB和Bochs调试器,具体的原理是 父进程(调试器)fork了一个子进程,来运行被调试的程序,当用户在调试器(Bochs举例)上输入b 0xXXXXXXXX指令时,父进程会将该地址的指令的第一个字节备份,再用0xcc(int3的机器指令)替换 这样再输入c运行,子进程运行到断点处就会触发3号中断,进行中断处理程序,但在此之前,还需保存当前的寄存器和栈的状态,所以用户查看寄存器和栈都是在栈中的值。 ....
[5]加载C语言内核(从汇编世界进入C语言世界)
生成C语言程序的过程: 说明:.o文件是可重定位文件,重定位指的是文件里面所用的符号还没有安排地址,这些符号的地址需要将来与其他目标文件“组成”一个可执行文件时再重新定位(编排地址) 符号是调用的函数或者变量 可执行文件可由几个目标文件组成,如kernel内核多个代码文件,生成kernel.bin文件 组成即链接操作 编排地址就是对程序中的代码安排对应的地址 具体链接调试过程: int _main(void) { while(1); return 0; } main.C:链接阶段必须明确程序的入口地址,默认的entry symbol 是_start,所以主函数函数名用这个表示。 (入口地址不是代码的起始地址,因为代码开始可能是数据,非指令) 接下来gcc -m32 -c -o main.o main.c ,再ld -m elf_i386 main.o -Ttext 0xc0001500 -o kernel.bin 前面生成可重定位文件,后面可执行文件 -c:生成目标文件,非可执行文件 -Ttext xxx:加载到起始虚拟地址xxx处 默认入口地址用_start表示,若自定义入....
了解x86下的特权级原理
特权级 为什么TSS中只有3个栈信息:因为任务处于最低的3特权级,而TSS中记录的栈是用于特权级从低特权级变成高特权级时,CPU会自动进行栈更新的作用,所以3特权级没有比它更低的特权级了,不需要放在TSS中。 那高特权返回到低特权级的情况下,cpu如何找到3特权级栈呢? 方法是:一般是用户程序调用函数进入依从代码段下的原函数前,在高特权级栈中记录返回栈指针和返回地址,之后retf或iret返回时可以从栈中恢复。 CPL: CPU当前特权级,等于CS段描述符的RPL值 DPL:“如果你想访问我,你应该具备什么样的权限” RPL:用什么权限去访问一个段 ,用于解决CPU“越权”问题 平坦模式下,用户进程不需要再提供选择子,所以调用门可以用中断门代替了 ?? 在调用内核服务例程时,段寄存器可能会加载到0特权级的段,但是在retf返回时CPU并不会压入段寄存器或者重新加载用户的段寄存器,这就导致返回到用户态后,存在段寄存器(CS和SS除外)还是内核特权级别的危险。 解决方法: Linux调用内核例程使用中断门,在中断处理程序返回前手动更新所有寄存器(恢复上下文)。 处理器中进行特权级检查,如....