ffutop

NaN-0NaN-0NaN

title: 理解 Linux Kernel (8) - 网络 author: fangfeng date: 2019-01-15 tags:

  • Linux
  • Kernel
  • Network

阅读更多


理解 Linux Kernel (7) - 字符设备

2018-12-28

相比较于块设备,字符设备无论从物理认知上,抑或是理论理解上,都存在着相当大的入门门槛。特别是在将字符设备与控制台、命令行终端混淆的时候,就更加难以进行分辨了。

回到字符设备本身,字符设备与块设备最主要的区别就在于块设备可以随机读写,而字符设备只能够顺序读,顺序写。

那么,常见的字符设备有什么?显示器、键盘、鼠标。

阅读更多


SQL 注入

2018-12-15

说实话此前对 SQL 注入的理解仅仅只是皮毛。当然,目前也是,只是有了一定程度的理解。

最近好像工具用得有些过头了,需要停下来整理下工具的实现原理。

更好地理解了工具实现,才能更加心安理得地使用工具。毕竟等别人怼的时候,还能够比较安心地回道: "我用不用现成的工具只是取决于我想不想自己再写一套"

当然,毕竟成熟的工具有更多的优化,这就不是短时间内我想不想自己写的问题了,哈哈。

阅读更多


正则表达式指数爆炸

2018-11-16

背景

昨天接触到一个很有意思的问题, 公司测试环境一台机器 CPU 跑到了 400%,导致该机器上的所有服务都挂掉了。

最后查到的原因竟然是正则表达式所引起的,大大出乎意料啊。虽然早就知道正则效率很差,但绝对没有想到会导致整个机器上服务崩溃的情况。

先简单展示下问题正则:

String regex = "(\\w+,?)+";
String val = "abcdefghijklmno,abcdefghijklmno+";
System.out.println(val.matches(regex));

最终的执行时间是 17s 左右。

相反,如果改成 String val = "abcdefghijklmno,abcdefghijklmno" ,实际执行时间 1ms 左右。

哈哈,完全不是一个量级的结果。

最后,当然是要找原因了:< 当然,有其它重要的事在耽搁,没时间去看 Java Regex 源码。不过,从正则本身下手反而是个好事情。毕竟几乎所有的编程语言都有对正则的支持。而同样的,都存在着这样的问题。那就可以大胆猜想其实是和语言本身无关,而在于正则规范本身了。

先给个结果,罪魁祸首就是指数爆炸

阅读更多


理解 Linux Kernel (6) - read & write

2018-11-11

前一篇已经描述对文件系统进行了宏观性的描述,这一篇,将以特定的文件读写操作为示例,串联对整个文件系统的基本操作。

首先先来看看平台相关的文件读写操作的 C 代码是怎样一个调用方式

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

int panic()
{
    fprintf(stderr, "%s (errno=%d)\n", strerror(errno), errno);
    return -1;
}

int main(int argc, char *argv[])
{
    /* 打开文件 frw.txt (以可读写 | 若不存在则新建的形式) */
    int fd = open("/root/frw.txt", O_RDWR | O_CREAT);
    if (fd == -1)
        return panic();

    /* 向文件写入 Hello World! 共计 12 个字符 */
    ssize_t wsize = write(fd, "Hello World!", 12);
    if (wsize == -1)
        return panic();

    /* 重定位文件读写指针 */
    off_t off = lseek(fd, 0, SEEK_SET);
    if (off == -1)
        return panic();

    char* buf = (char *) malloc(wsize);
    /* 读取文件内容 */
    ssize_t rsize = read(fd, buf, wsize);
    if (rsize == -1)
        return panic();

    printf("%s\n", buf);
    free(buf);
    /* 关闭文件 */
    int stat = close(fd);
    if (stat == -1)
        return panic();

    return 0;
}

阅读更多


理解 Linux Kernel (5) - 文件系统(宏观描述)

2018-10-14

用惯了类 Unix 系统,应该说文件系统是日常最常接触的一个操作系统模块之一了。

$ ls
Applications Network      Users        bin          data         etc          net          sbin         usr
Library      System       Volumes      cores        dev          home         private      tmp          var

但是,究竟什么是文件系统? 为什么需要文件系统? 难道文件不是简单地存储到存储设备一块连续区域的吗?

阅读更多


理解 Linux Kernel (4) - 任务调度

2018-10-12

前面几节已经描述过,对于单核 CPU 来说。CPU 就处于不断地执行指令的过程(或者通过 hlt 指令直接停止工作)。

针对于每一个程序来说,这个程序执行流程是通过 CPU 中几组寄存器(通用寄存器、段寄存器、控制寄存器等) 和存储在内存中的代码和数据协作完成的。

如果要达到单核多任务的目的,首先要做的就是完成对几组寄存器中当前值的保存(我称之为保存现场)。而对于内存来说,多个任务的代码、数据同时存在内存是完全合理且可行的。毕竟相较于有限的寄存器,内存实在是太大了(相对而言)。

阅读更多


理解 Linux Kernel (3) - 操作系统启动

2018-10-06

这次拖得有够久的,毕竟需要将知识串联起来并不是一件容易的事情。更何况很多内容可以说和常理(个人理解的常理)有了比较大的偏差。

不过确实比较有意思。从引导程序到操作系统启动,这中间究竟经历了多少流程呢?

由于有了前几节的内容,这里不会再对引导程序及汇编语法做过多的介绍。而着重在于整个流程的描述。

阅读更多


Understand MAIL

2018-09-27

在网络协议上,高层协议确实比底层协议更容易理解,也更加的人性化。 传输层的 TCP, UDP 都还停留在各种字节内容的整合和校验上,而更上层的应用层协议就已经能够直观到通过直接解读就能理解其每条消息的含义了。

阅读更多