0%

华清远见实训笔记

VmWare(虚拟机)通过软件模拟出来的计算机

Ubuntu linux操作系统的一个发行版。

嵌入式设备

1
机械手表 智能手表

操作系统

Linux

  • 开源 免费
  • 内核可剪裁
  • linux一切皆文件
  • linux的文件系统像是一颗倒置的树
  • 多用户 多任务

一、linux基础指令

权限

  • sudo —临时获取超级用户的权限

  • su — 切换用户

    1
    2
    su --- 切换到root用户
    su 用户名 --- 切换到指定的用户

1.导航命令

  • pwd – print work dirctory — 打印当前的绝对路径
1
2
hqyj@ubuntu:~$
用户名@主机名: $
  • ls — 将指定目录下的内容输出到终端
1
2
3
4
5
6
7
8
9
10
11
12
/:根目录
ls 路径
ls [选项] 路径
选项:-l 查询指定目录下的详细信息
linux的七大文件类型:lsp - bcd
l:链接文件 -- 快捷方式
s:套接字文件
p:管道文件
-:普通文件 --
b:块设备文件
c:字符设备文件
d:目录文件 -- 文件夹
  • cd — change dirctory — 改变路径
1
2
3
4
cd 路径 --- 进入指定的路径
.. :上一级目录
~ :用户目录 === /home/hqyj
/ :根目录

2.目录文件

  • mkdir – make directory

    1
    mkdir 目录文件名
  • rmdir – 删除空目录文件

    1
    rmdir 目录文件名
  • rm

    1
    rm  -r  目录文件名 -- 删除目录文件

3.普通文件

  • touch – 创建普通文件

    1
    touch 普通文件名1 普通文件名2 。。。。。。
  • rm – 删除普通文件

    1
    rm 普通文件名
  • cat – 将普通文件的内容输出到终端

    1
    cat 普通文件名

4.复制和剪切

  • cp – copy 赋值

    1
    2
    cp 原文件名 目标文件名
    cp -r 源目录文件名 目标目录文件名
  • mv –move 剪切

    1
    mv 原文件名 目标文件名
  • clear — 清空终端

二、编辑器

1.vi(vim)编辑器

  • 打开vi编辑器
1
终端输入:vi 1.c --- 使用vi编辑器打开1.c文件,如果1.c文件不存在则创建
  • 命令行模式
1
2
3
4
5
6
7
8
9
10
移动光标:键盘上的上下左右键
h:光标向左
j:光标向下移动
k:上
l:右
yy:复制光标所在行
nyy:复制n行 -- n是一个整数
dd:剪切光标所在行
ndd:
p:在光标的下一行粘贴
  • 命令行模式 ->插入模式(编辑模式)
1
2
3
4
5
6
i:从当前光标之前开始插入
I:
a:从当前光标之后开始插入
A:从行末开始插入
o:从光标所在行的下一行开始插入
gg=G :全文调整缩进
  • 插入模式–>命令行模式 Esc

  • 底行模式

    1
    2
    3
    :w  --- 保存
    :q --- 退出
    :wq --- 保存并退出

2.gedit

1
gedit test.c

三、编译器 – gcc

  • 使用方法

    1
    2
    3
    4
    gcc 1.c --- 编译1.c 如果没有语法错误则生成可执行文件 ->默认a.out
    ./a.out
    gcc test.c -o test
    ./可执行文件名
  • 预处理

    1
    2
    对原文件中的一些预处理指令(#include #define #ifndef)的处理,头文件展开、宏替换、清除注释
    gcc -E 1.c -o 1.i
  • 编译

    1
    2
    将预处理之后的文件转换汇编文件 ,检查语法。
    gcc -S 1.c -o 1.s
  • 汇编

    1
    2
    将汇编文件转换成目标机器能够执行的二进制文件.o -- 目标文件
    gcc -c 1.c -o 1.o
  • 链接

    1
    2
    将所有目标文件链接(库函数)在一起生成可执行文件。
    gcc 1.o

四、指针

  • 什么是什么?

    1
    2
    3
    4
    指针就是地址
    地址:内存最小单元(字节)的编号 --一般用十六进制形式表示
    1111 1111 1111 1111 1111 1111 1111 1111
    FF FF FF FF
  • 指针变量

    1
    指针变量是变量占据内存空间用来保存地址

1.指针变量定义的一般形式

1
2
3
4
<数据类型> * 指针变量名;
int *p;

char *p;

2.指针的偏移

1
2
P + 1 :向高地址偏移一个数据类型单位
P + N :想高地址偏移N个数据类型单位

作业:验证自己当前计算机采用那种存储方式(大端/小端)

1
小端:数据的低位保存到地址空间----小段字节序

3.函数指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
函数返回类型 (*指针变量名)(函数形参列表);
int steam(int (*pfunc)(int,int),int x,int y)
{
p(x,y);
return 0;
}

steam(Pbug)




int Pubg(int x,int y)
{
return 0;
}
int Apex(int x,int y)
{
return 0;
}
1
2
3
4
5
int Pubg(int x,int y,char* ch)
{
return 0;
}
int (*pfunc)(int,int,char*)
1
2
3
4
5
6
7
8
9
10
11
int (*pfunc)(int ,int );


int func1(int a,char b)
{

}
int func2(int a,int a)
{

}
1
2
3
4
5
man:linux 提供一种帮助手册可以用来查询命令、库函数、系统调用函数的使用方法。
man page 命令/库函数/系统调用函数
1:命令
2:系统调用函数
3:库函数

五、项目

云存储

1.基础功能

  • 上传
  • 下载
  • 查询
  • 断点续传(附加)

2.知识点

  • linux基础指令

  • C语言

  • 目录IO(查询)

    1
    2
    opendir
    readdir
  • 文件IO (上传/下载)

    1
    2
    3
    4
    5
    open
    read
    write
    lseek
    close
  • Linux网络编程 — TCP服务器搭建

3.具体流程

  • 服务器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    搭建TCP服务器 socket bind listen 
    等待连接 accept
    等待处理请求
    if(buf == "list")
    {
    查询目录信息 --->发客户端
    }
    else if(buf == "load")
    {
    打开对应文件
    将文件数据发送给客户端
    }
    else if(buf == "upld")
    {
    创建文件
    等待接收客户端发送文件数据
    将接收到的文件数据写入本地文件
    }
  • 客户端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    搭建TCP客户端 
    发起连 connect
    发起请求
    if(buf == "list")
    {
    //等待接收服务器发过来的目录信息
    }
    else if(buf == "load")
    {
    打开对应文件
    接收文件数据
    将接收到的文件数据写入本地文件
    }
    else if(buf == "upld")
    {
    打开文件
    发送文件数据到服务器
    }

在线翻译

  • TCP服务器 UPD服务器

  • sqlite3数据库

    1
    2
    sudo apt-get install sqlite3
    sudo apt-get install libsqlite3-dev

2.使用库函数来操作数据库文件

  • #include <sqlite3.h>

  • gcc xxxxx.c -lsqlite3

  • 打开数据库文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int   sqlite3_open(char  *path,   sqlite3 **db)

    功能:打开sqlite数据库

    path: 数据库文件路径 //如果指定的文件不存在则创建

    db: 指向sqlite句柄的指针
    sqlite3 *db;
    sqlite3_open("xxxx.db",&db)

    返回值:成功返回0,失败返回错误码(非零值)

  • 关闭数据库文件

    1
    2
    3
    4
    5
    6
    int   sqlite3_close(sqlite3 *db);

    功能:关闭sqlite数据库

    返回值:成功返回0,失败返回错误码

  • 打印错误信息

    1
    2
    3
    4
    const  char  *sqlite3_errmsg(sqlite3 *db);

    返回值:返回错误信息

  • 执行sql语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    int   sqlite3_exec(sqlite3 *db, const  char  *sql,  sqlite3_callback callback, void *para,  char **errmsg);
    功能:执行SQL操作
    db:数据库句柄
    sql:SQL语句
    callback:回调函数 //在执行select查找时才需要该参数 ----》NULL
    para:传递给回调函数的参数。
    errmsg:错误信息指针的地址// --->NULL
    返回值:成功返回0,失败返回错误码

    • callback

      1
      2
      3
      4
      5
      6
      7
      8
      9
      typedef  int (*sqlite3_callback)(void *para, int f_num, char **f_value, char **f_name);

      功能:每找到一条记录自动执行一次回调函数
      para:传递给回调函数的参数
      f_num:记录中包含的字段数目
      f_value:包含每个字段值的指针数组
      f_name:包含每个字段名称的指针数组
      返回值:成功返回0,失败返回-1

      1、IP地址 – 在网络当中唯一标识一台主机。

      • IPv4 –4字节–32bit

        1
        2
        3
        点分十进制:192.168.6.23 --->字符串--->便于传播记忆
        二进制:11000000 10101000 00000110 00010111
        inet_addr("192.168.6.23");//将点分十进制的字符串表示的ip转换成网络字节序
      • IPv6 –128bit

      2、端口号 –port

      • 标识主机当中的一个进程

      • unsigned short – 0-65535

        1
        2
        3
        4
        5
        1-1024:系统应用的端口
        1025-5000:常用应用端口
        5001-65535:用户端口
        htons(6666) --- 将6666转换成网络字节序
        htonl

      3、字节序

      • 主机字节序host byte order

        • 小端字节序

          1
          数据的低位保存低地址空间 ---》低低小
        • 大端字节序

          1
          数据的低位保存高地址空间
      • 网络字节序 network byte order—大端

      4.套接字

      • 本质:网络进行通信的两个进程的端点的抽象,给应用进程提供使用各层协议的接口。

      • linux中的一种系统调用–>socket,通过socket可以使用内核当中集成各层网络协议。

      • 是一种特殊的文件描述符—>套接字文件描述符

      四、TCP服务器

      1.TCP服务器/客户端搭建流程

      • 服务器:socket->bind->listen->accept->read/write->close
      • 客户端:socket-> connect->read/write->close

      2.TCP服务器相关接口函数

      • socket

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        #include <sys/types.h>          /* See NOTES */
        #include <sys/socket.h>

        int socket(int domain, int type, int protocol);
        功能:
        在内核当中创建一个端点并且返回一个文件描述符指向该端点。
        文件描述符:当前进程能够分配最小非负整数。
        参数:
        domain:地址协议族
        AF_INET:ipv4
        AF_INET6:ipv6
        AF_UNIX:本地套接字
        type:
        SOCK_STREAM:提供有序、可靠、全双工、基于字节流数据的传输。---》唯一对应TCP
        SOCK_DGRAM:唯一对应UDP
        SOCK_RAM:原始套接字
        protocol:
        一般填0
        返回值:
        成功:返回一个文件描述符---》套接字文件描述符
        失败:-1
      • bind

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        #include <sys/types.h>          /* See NOTES */
        #include <sys/socket.h>

        int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
        功能:
        为socket创建的套接字绑定ip和端口、地址协议族。
        参数:
        sockfd:socket返回的文件描述符---》套接字文件描述符
        addr:
        struct sockaddr {//通用地址结构体
        sa_family_t sa_family;
        char sa_data[14];
        }
        struct sockaddr_in {//ipv4地址结构
        sa_family_t sin_family; /* address family: AF_INET */
        in_port_t sin_port; /* port in network byte order */
        struct in_addr sin_addr; /* internet address */
        };

        /* Internet address. */
        struct in_addr {
        uint32_t s_addr; /* address in network byte order */
        };
        addrlen:地址结构体的长度。
        返回值:
        成功:0
        失败:-1
      • listen

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        #include <sys/types.h>          /* See NOTES */
        #include <sys/socket.h>

        int listen(int sockfd, int backlog);
        功能:将绑定的套接字挂起让内监听,并且设置监听队列。
        参数:
        sockfd:绑定之后的套接字
        backlog:监听队列的长度 --- >0
        返回值:
        成功:0
        失败:-1
      • accept

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        #include <sys/types.h>          /* See NOTES */
        #include <sys/socket.h>
        int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
        功能:从监听队列种拿出队列的第一个请求并且返回一个新的文件描述符与该请求对应。
        参数:
        sockfd:监听之后的套接字
        addr :保存客户端的ip地址 ---->NULL
        addrlen:ipv4地址结构体的长度 ---->NULL
        socklen_t addrlen = sizeof(struct sockaddr_in);
        accept(sockfd,xxxxxx,&addrlen);
        返回值:
        成功:返回的一个新的文件描述符(连接套接字)与连接的客户端一一对应
        失败:-1
        注意:当read函数去读accept返回的连接套接字时如果连接套接字对应的缓冲中没有数据那么read会阻塞直到有数据返回实际读到的字节数。
        如果read返回值为0代表客户端断开连接
      • read/write

      • close

      • connect

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        #include <sys/types.h>          /* See NOTES */
        #include <sys/socket.h>

        int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
        功能:
        将sockfd所引用的套接字连接到addr所指定的服务器。
        参数:
        sockfd:socket创建的套接字文件描述符
        addr:服务器地址
        addrlen:服务器地址结构体的大小
        返回值:
        成功:0
        失败:-1

      作业1:编写tcp客户端(分享)

      练习:编写TCP服务器和客户端,客户端连接成功之后,服务器给客户端发送一张图片。

      3、TCP服务器模型

      • tcp服务器

        1
        2
        3
        4
        5
        6
        7
        socket();
        bind();
        listen();
        accept();
        read()/write();
        close();

      • 循环服务器

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        socket();
        bind();
        listen();
        while(1)
        {
        accept();
        while(1)
        {
        read()/write();
        }

        }

        close();
        gg=G:vi自动调整缩进

      • 多进程并发服务器

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        socket();
        bind();
        listen();
        while(1)
        {
        accept();
        pid_t pid = fork();
        if(0 == pid)
        {
        while(1)
        {
        read()/write();
        }
        }
        }

      • 多线程并发服务器

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        socket();
        bind();
        listen();
        while(1)
        {
        connfd = accept();
        pthread_t tid;
        pthread_create(&tid,NULL,pfunc,&connfd);
        pthread_detach(tid);

        }
        void *pfunc(void *arg)
        {
        int connfd = *(int *)arg;
        while(1)
        {
        read()/write();
        }
        }
        netstat -apn | grep "6666"
        wireshark ---抓包工具
        sudo apt-get install wireshark

      作业1:编写文件传输服务器(TCP) ,查询目录下内容。

      作业2:编写时间服务器。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      创建套接字
      绑定
      监听
      等待连接
      while(1)
      {
      获取系统时间发送给客户端;
      }

      //////
      创建套接字
      发起连接
      while(1)
      {
      接收服务器发送过来时间信息
      }

      分享:TCP三次握手四次挥手,并且分析TCP协议头

      五、UDP服务器

      1、UDP服务器搭建流程

      1
      2
      3
      4
      socket(AF_INET,SOCK_DGRAM,0)//创建套接字
      bind()//绑定
      recvfrom()//等待接收数据

      2、UDP客户端的的搭建流程

      1
      2
      3
      socket(AF_INET,SOCK_DGRAM,0)//创建套接字
      sendto()//发送数据到指定的地址

      3、UDP相关接口函数

      • recvfrom

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
        struct sockaddr *src_addr, socklen_t *addrlen);
        功能:接收对端发送的消息,并且将对端的地址信息保存到src_addr所指向的结构体。
        参数:
        sockfd:套接字文件描述符
        buf:接收数据的缓冲区
        len:要从sockfd指定的缓冲读取len个字节的数据
        flags:0
        src_addr:保存对端地址
        addrlen:对端地址结构体的长度
        socklen_t addrlen = sizeof(struct sockaddr_in);
        recvfrom(xxx,xxx,xxx,xxx,xxx,&addrlen)
        返回值:
        成功:返回实际接收到的字节数。
        失败:-1

        注意:recvfrom是一个阻塞函数。

      • sendto

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
         ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
        const struct sockaddr *dest_addr, socklen_t addrlen);
        功能:利用sockfd将buf里面的前len个字节发送到dest_addr所指定的服务器/客户端去。
        参数:
        sockfd:套接字文件描述符
        buf:发送缓冲区
        len:发送的字节数
        flags:0
        dest_addr:对端的地址
        addrlen:对端地址结构体的长度
        返回值:
        成功:返回实际发送的字节数
        失败:返回-1

      文件IO

  • man 手册第二页

  • open

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
          #include <fcntl.h>

    int open(const char *pathname, int flags);
    int open(const char *pathname, int flags, mode_t mode);
    功能:站在内核个角度打开一个文件,并且返回一个文件描述符,该文件描述指向打开的文件。
    文件描述符:是当前系统可分配的最小的、非负的整数。
    0:标准输入
    1:标准输出
    2:标准错误
    参数:
    pathname:文件名及路径
    flags :设置打开文件的权限必须包含以下三个选项之一
    {
    O_RDONLY:只读
    O_WRONLY:只写
    O_RDWR:读写
    }
    O_CREAT:如果打开的文件不存在则创建
    注意:一旦flags选择了O_CREAT那么open函数必须要传第三个参数mode
    mode:文件创建的权限(0777)
    返回值:
    成功:返回文件描述符
    失败:-1
  • read

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <unistd.h>

    ssize_t read(int fd, void *buf, size_t count);
    功能:从fd所指向的文件中读取count个字节的数据到部分所指向的缓冲区
    参数:
    fd:已经打开的文件描述符
    buf:缓冲区首地址
    count:要读取的字节数
    返回值:
    成功:返回实际读到的字节数
    注意:如果read返回0代表读到了文件的末尾
    失败:返回-1
  • write

    1
    2
    3
    4
    5
    6
    7
    8
    #include <unistd.h>

    ssize_t write(int fd, const void *buf, size_t count);
    功能:将buf缓冲里面的前count个字节的数据写入fd所指向的文件。
    参数:
    返回值:
    成功返回实际写入的字节数
    失败返回-1
  • close

目录IO

  • opendir

    1
    2
    3
    4
    5
    6
    7
    8
    #include <sys/types.h>
    #include <dirent.h>

    DIR *opendir(const char *name);
    功能:
    参数:
    返回值:

  • readdir

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <dirent.h>
    struct dirent *readdir(DIR *dirp);
    功能:
    参数:
    返回值:
    struct dirent {
    ino_t d_ino; /* Inode number */
    off_t d_off; /* Not an offset; see below */
    unsigned short d_reclen; /* Length of this record */
    unsigned char d_type; /* Type of file; not supported
    by all filesystem types */
    char d_name[256]; /*保存目标目录中某一个文件名 */
    };


    套接字属性

  • getsockopt()

  • setsockopt()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int getsockopt(int sockfd, int level, int optname,void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
参数:
sockfd:套接字
level:设置属性层
SOL_SOCKET:通用套接字层
IPPROTO_IP:IP层
IPPRO_TCP:TCP层
optname:指定操作,一般用宏表示
optval:设置属性对应的值
optlen:设置属性对应值长度

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

  • level

    • SOL_SOCKET

      optname optval类型
      SO_BROADCAST  允许发送广播数据 int
      SO_DEBUG     允许调试 int
      SO_DONTROUTE  不查找路由 int
      SO_ERROR     获得套接字错误 int
      SO_KEEPALIVE 保持连接 int
      SO_LINGER     延迟关闭连接 struct linger
      SO_OOBINLINE   带外数据放入正常数据流 int
      SO_RCVBUF     接收缓冲区大小 int
      SO_SNDBUF     发送缓冲区大小 int
      SO_RCVLOWAT    接收缓冲区下限 int
      SO_SNDLOWAT   发送缓冲区下限 int
      SO_RCVTIMEO    接收超时 struct timeval
      SO_SNDTIMEO    发送超时 struct timeval
      SO_REUSEADDR  允许重用本地地址和端口 int
      SO_TYPE       获得套接字类型 int
      SO_BSDCOMPAT   与BSD系统兼容 int
    • IPPROTO_IP

      optname optval类型
      IP_ADD_MEMBERSHIP 将指定IP加入到组播组中 struct ip_mreq
      IP_MULTICAST_IF 允许开启组播报文的接口 struct ip_mreq
    • IPPRO_TCP

      optname optval类型
      TCP_MAXSEG TCP最大数据段的大小 int
      TCP_NODELAY 不使用Nagle算法 int
-------------本文结束感谢阅读-------------
vivo50