Linux学习笔记一
本文是学习linux时所做的笔记 有些内容没有过多的研究
http://ftp.sjtu.edu.cn/ubuntu-cd/14.04/下载 ubuntu-14.04.6-server-amd64.iso
安装完后要在linux中安装ssh
sudo apt-get install openssh-server 回车 然后再输入y回车
安装完成后 ps -e | grep ssh (注意中间那个是杠)
用ip addr得到ip地址
回到putty输入这个ip地址连接上服务器
shell必备命令
用命令解析器去执行对应的程序
命令行区分大小写
行有$或者#则可以输入命令提示符
- tab命令补全(输入一些字符后,按下tab键) 如果有两个重复的,他不会补全,会给你几个选项,你按照这个选项再敲几个字母再tab会给你补全
- 通配符 *任意长度的字符串 ?匹配一个字符
- []用于匹配所有出现在方框中的字符,比如 is text[1-2] 所以会选择text1和text2
- ##或者--会被认为是注释不会进行执行
- main命令 比如main is会输出is的所有操作 j向下动 k往上翻动 空格是翻页 q是退出
- pwd打印当前目录 cd /到根目录下面 注意有个空格
- 切换为超级用户,不能直接用su直接提升到root权限,要用sudo来获得root权限 也就是输入sudo su 此时便可以创建目录了 mkdir demo1 然后ls -la便可以显示出来 root是超级用户
- 如果su kz切换成kz用户那么rm demo1回车 输入y 回车则显示权限不够 可以对这个进行提升权限 sudo rm -r demo1 则去提升了权限 也就是提升了对demo1删除的权限
- 终端翻页 shift+pageup shift+pagedown
- 清屏 ctrl+l 或者输入clear
- man man查看帮助文件
延伸
光标
光标所在的字节是光标后面一个字节
- 移动到开头 Ctrl+a
- 移动到末尾 ctrl+e
- 往前移动 ctrl+b
- 删除光标所在的字节 ctrl+d 前面的字节用回退就行
- 删除光标前面的 ctrl+u 如果删除整行 将光标移动到最后ctrl+e 再按 ctrl+u
提示 tab
- tab命令补全(输入一些字符后,按下tab键) 如果有两个重复的,他不会补全,会给你几个选项,你按照这个选项再敲几个字母再tab会给你补全
- 用于路径补全,比如cd /src/hist不会拼了如果存在这个路径的话按tab键
- 按两下会给你能够提供的选项,如果路径不知道的时候 比如cd /src/两次tab会将所有的下一个目录显示出来
目录
用ls /会列出所有的目录
- bin目录存放经常使用的命令 比如ls
- boot存放的是启动linux使用的核心文件
- dev存放的linux硬件,将硬件抽象出文件
- etc配置文件
- home是linux下的用户
- lib是动态库
- media挂载u盘等内容,如果可以识别,那么就可以去这里进行读取
- mnt是不能识别的设备,让你自己去挂载的
- root是超级用户自己的目录
- sbin是系统管理员使用的系统管理程序
- usr不是user,它是用户资源目录,存放很多的用户程序和文件
- /usr/bin是用户使用的应用程序
- /usr/sbin是超级用户使用的比较高级的管理程序和系统使用程序
- var存放不断扩充的东西,习惯于将经常修改后的的目录存放到这个目录里面
路径
绝对路径 以反斜杠开始,是从根目录开始的 cd /usr/bin/
相对路径
- cd ./是当前目录开始
- cd ../上一级目录开始
- cd - 是切换到上一个使用的目录也就是刚才用的目录,再按一次会回来
- cd ~回家 或者直接cd 直接回家
- cd /是到达根目录,相当于绝对路径
pwd可以查看当前的路径 其实直接看命令行前面的内容便知道
命令行前面的内容
root@ecs-kc1-small-1-linux-20210406183446:~# 第一个是用户名 ,@是at的意思 第三个是设置的主机名 波浪线是代表的家 比如很多用户,有的话表名正在用户的家里
因此:后面
因此使用 cd ~会进入他的家目录
#代表超级用户
$代表普通用户 切换到超级用户 sudo su 切换的时候看清让你输入谁的密码 ;用exit退回普通用户
文件和目录操作
- 首先查看目录 这里用的是tree 需要安装 安装代码为sudo apt-get install tree
在某个目录下面输入tree,则会以树状的形式输出目录的结构 如果输入tree +某个子目录会查看子目录的内容
颜色显示
- 白色 普通文件
- 蓝色 目录文件
- 绿色 可执行文件
- 红色 压缩文件
- 青色 链接文件 相当于快捷方式
- 黄色 设备文件 block块 char 字符 fifo管道
注意是一般情况是,但有时候不一定
-
文件操作命令
ls命令
- ls不带任何参数则会列出所有的文件和子目录
- ls -F会进行分类的显示
- ls -a显示隐含的文件 a是all的意思 如果一个文件前面带. 则说明是隐藏文件
- ls -l查看文件的各种属性
- 需要注意的是 如果是目录的话 仅是目录本身自己所占的空间大小,目录始终占4096 不包括里面包含的文件大小
- 如果是链接的话 比如上图的copy文件 他后面指明指向的文件
dir命令
- 和ls差不多但功能比ls少
建立目录mkdir
- mkdir不带任何参数 则会创建相应目录 mkdir x1 x2 x3则会创建三个目录 tree一下看看
- mkdir -p x4/x3/x2 则会创建三个连串的子目录 tree一下看看 -p也可以放到最后
删除rm
- rmdir 文件名 不实用
- rm 文件名 -r r是递归的意思 或者理解为联系的意思 将所有与他有联系的子目录全部删除
- rm 文件名 -ri 当删除的时候会提示你 i可以理解为第几个 在for循环中的第i个
- 如果rm 文件名 -i会提示你是否进行删除 且标注文件的属性 因此-i可以理解为提示
创建文件touch
- touch 使用touch时如果不加后缀 则会默认不加文件属性
- 对于touch 如果有重复文件则会修改文件的时间但不会修改文件的内容 如果没有文件将会创建
移动mv既可以移动又可以改名
- 不加任何参数 mv text ./x1/表示将text移动到当前目录的x1的目录中,如果存在重名那么将会进行替代
- 加上-i 比如mv -i text ./x1/ 移动后如果存在重名会提示你是否进行替代 -i是提示
- 改名 mv a1 a2
- 加上-b 比如mv -b text ./x1/ 移动后如果存在重名会会名字末尾加上~
复制cp
- 不加任何参数 cp text1 text2 会将text1的内容复制到text2中,如果存在重名则将进行覆盖
- 加上-i 比如cp -i text1 text2 如果存在重名则会提示你是否进行覆盖 因此总结归纳 -i是如果有异常则会抛出来
- 加上-b 比如cp -b text1 text2 如果存在重名会在后面加上~
- 加上-r 比如cp -r x1 x4/ 会将x1连同x1下面的所有子目录复制到x4里面去 因此总结归纳-r是进行递归的操作 x1是本身自己 x2/是到他里面
- cp x1/* x2/* 会将x1里面的东西复制到x2里面
删除 rm
- 不加任何参数则会直接删除
- 加上-i 删除时会进行提醒
- -f 强制性的删除文件或者相应目录
- -r 将子目录以及其中的文件一起删除 不能rm -r / 此时系统无法使用
重命名或者移动mv
例子:将目录A重命名为B
mv A B
例子:将/a目录移动到/b下,并重命名为c
mv /a /b/c
查看文件内容
- cat 文件名 如果内容比较长 将不会显示
- more 文件名 会显示百分之几十的内容,如果还要看按回车会一行一行的出来 如果按空格直接翻页 如果不想看了 按一下q直接出来 如下图 缺陷是不能往回看
- less 文件名更加智能 它可以往回看 按ctrl +b
- 但一般都用vi来查看 不用more和less
- head -5 文件名 是前五行 tail -5文件名 是后几行 不加-几的话是默认十行
链接
ln 文件1 文件链接 这里是硬链接 是映射的文件内容,文件会加一 也就是如果删除了文件,系统不会删除这个文件,直到文件链接删除了才会删除这个文件
目录不能创建硬链接但可以创建软链接
其他文件操作
wc获取文本文件的行数 字节数 名字等等
od
du查看文件的大小 du -h
df -h查看磁盘使用情况
which命令
会查找命令所在的地址 ls是通过bin里面的ls执行的
但是cd是内建命令查找不出来
权限修改
ls -la会列出所有文件的属性,第一个属性比如 d rwx rwx rwx 一共十个字母 第一个rwx是用户的权限 第二个是用户所在组的其他成员对文件的权限 第三个是其他人的权限
两种修改方法
- 文字设定法
比如chmod a+w test 会给所有人加上w权限
chmod a=w test 会给所有人权限只有w 消掉其他的权限
chmod u-w test 会给所有者去掉w权限
- 数字设定法
chmod 777 test
三位二进制
vim编辑器 看笔记二
vim是从vi发展过来的
首先vim ./test在当前路径下打开test文件,如果没有则会自动新创建一个,此时不能插入需要切换到插入模式,有插入模式和命令两种模式
显示行号 set nu;
插入模式
在上面打开文件后按键进行插入
- 按a后,下面显示插入,此时是在光标后面插入
- 按i后,在光标所在位置插入
- 按o后,在光标所在位置的下一行插入
- Esc 按后会进入命令模式
- : 会进入行命令模式
命令模式
在上面写完以后,按Esc键进入命令模式 如果想要保存的话要确保自己拥有权限
- 输入:w会保存文件
- 输入:wq会保存修改并退出
- 输入:q会离开
- 输入:q! 强行退出放弃修改
- : w 别名 另存为别名
搜索模式
在命令模式的前提下
- /加上要搜索的字符串回车会定位到那里,这个是用于向下查找
- ?加上要搜索的字符串会向上查找
文件阅读
- cat cat用来一次性查看全部文本文件的内容,后面跟上文件名作为参数 也可以带上-你显示每行的行号,如果文件长达几十上百页,不建议使用cat
- more 用来分页查看文本文件,空空个翻页;回车向下滚动一行 Q键退出
- less 更人性化的文本阅读器
查找
find ./ -name test2
文件的参数 b块设备文件 f普通文件 c字符设备文件 p命名管道 d目录文件 l符号链接
加上参数后,比如 find ./ -type f -name test2
-atime n查找最后一次使用在n天前的文件 ,n使用负数表示
-mtime n查找最后一次修改在n天前的文件
locate
grep 使用正则表达式
开启编程
看笔记二
首先安装gcc apt-get install gcc
vim ./hello.c创建一个文件 进入编写代码
gcc hello.c
然后ls -la查看编译后的文件 发现有一个a.out 然后打开这个也即./a.out 打开当前文件下的a.out
发现问题就是 用gcc编译竟然编译成a.out,因此可以用 gcc hello.c -o hello 这样的话编译文件会变成hello 再打开 ./hello
网络服务器开发
实现回声服务器的客户端/服务器程序,客户端通过网络连接到服务器
socket通信3要素
- 通信的目的地址
- 使用的端口号
- 使用的传输层协议 如TCP UDP
bzero($server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_add.s_addr=htoml(INADDR_ANY);
server_addr.sin_port=htons(SERVER_PORT);
bind(sock,(struct sockaddr *)&server_addr.sizeof(server_addr));
listen(sock,128):
printf("等待客户端的连接\n");
int done=1;
while(done){
struct sockaddr_in client;
socket client;
socklen_t client_addr_len;
client_addr_len=sizeof(client);
accept(sock,(struct sockaddr *)&client_addr_len);
}
int sock;
struct sockaddr_in server_addr;
//1.美女创建信箱
sock=socker(AF_INET,SOCK_STREAM,0);
//2.清空标签,写上地址和端口号
bzero(&server_addr.sizeof(server_addr));
server_addr.sin_family=AF_INET;//选择协议族ipv4
server_addr.sin_addrs=htonl(INADDR_ANY));//监听本地所有IP地址 inaddr_any
server_addr.sin_port=htons(SERVER_PORT);//绑定端口号
//实现标签贴到收信的信箱上
bind(sock,(struct sockaddr*)&server_addr,sizeof(server_addr));
//把信箱挂到传达室,这样,就可接收信件了
listen(sock,128);
从别处复制的
//创建套接字
int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//创建sockaddr_in结构体变量
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //计算serv_addr的长度,并用0填充,返回地址
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址
serv_addr.sin_port = htons(1234); //端口
//将套接字和IP、端口绑定
bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));//先使用sockaddr_in的变量在,强制类型转化为sockaddr类型
服务器端要用 bind() 函数将套接字与特定的 IP 地址和端口绑定起来,只有这样,流经该 IP 地址和端口的数据才能交给套接字处理
socket服务器和客户端都需要这个,socket使用整形来表示的
套接字是一个特殊的文件是一个伪文件,对套接字进行处理一般就是用对文件的处理,读写套接字和读写文件是一样的。
ip地址加上TCP端口号 或者UDP端口号
套接字是成对出现的,建立连接的两个进程各自有一个socket来标识,这两个socket组成的socket pair就唯一的标识一个连接
全双工通信,读和写可以同时的进行
客户端是建立socket,然后连接,然后读或者写,然后关闭
服务器端是建立socket,然后贴上这个socket然后监听,然后接受,然后读或者写最后关闭
关闭是四次挥手
网络字节序
两种字节序
- 大端字节序 -低地址高字节,高地址低字节
- 小段字节序-低地址低字节,高地址高字节 一般用这个
比如1001十六进制是0x03 e9 大端地址就是e9 03 小端地址是03 e9
发送的时候地址是从小地址向大地址发送的,接收主机也是从小地址开始保存的
网络数据流使用大端字节序,因此在发送前需要进行字节序额转换
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong); h是主机 to n是network
unint16_t htons(uint16_t hostshort) s表示16位短整数 l是32位长整数 前面那个unint是返回的类型
所以才会有
server_addr.sin_addr=htonl(INADDR_ANY);//监听本地所有的ip地址,ip地址是32位,用long的32位
server_addr.sin_port=htons(SERVER_PORT);//绑定端口号,端口号是16位的,用short表示16位
sockaddr数据结构
struct sockaddr_in server_addr
bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr));
struct sockaddr很多网络编程函数诞生遭遇IPv4协议,那时候都是用的是sockaddr结构体,为了向前兼容,现在sockaddr退化成了(void*)的作用,传递一个地址给函数,至于这个函数sockaddr_in 还是其他的,由地址族确定,然后函数内部再强制类型转化为所需的地址类型
因此像bind,accept函数的参数都用struct sockaddr*类型表示,在传递参数之前要强制类型转换一下
struct sockaddr{ //16个字节
sa_family_t sa_family; //IPv4是AF_INET IPv6是AF_INET6
AF
char sa_data[14];
}
struct sockaddr_in{ //16个字节
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr; //因特网的地址
}
struct in_addr{
uint32_t s_addr; //因特网的地址是32位无符号的整形数 要将整形转换为字符串
}
因为16个字节和16个字节都一样,因此要进行强制转换 将server_addr转换为sockaddr
bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr));
IP地址转换函数
一般写ip地址都是字符串的类型,但是在网络中是用整数,因此需要进行类型的转换
#include<arpa/inet.h>
//将字符串的值转为网络字序的值
int inet_pton(int af,const char*src,void *dst);
//网络字序的值转为字符串
const char*inet_ntop(int af,const void*src,char*dst,socklen_t size)
af取值可以选为AF_INET和AF_INET6
例如:
char ip[]="2.3.4.5";
struct sockaddr_in server_addr;
inet_pton(AF_INET,iP,&server_addr.sin_addr.s_addr);
将ip地址转换,转换后的值放入到server_addr.sin_addr.s_addr指向的地址里面
socket函数
#include <sys/types.h>/* See NOTES *
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain:
AF_INET这是大多数用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址
AFINET6与上面类似,不过是来用IPv6的地址
AF UNIX本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用
type:
SOCK_STREAM 即sock_stream流 这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
SOCK_DGRAM 即sock_dgram这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
SOCK SEQPACKET 即sock_seqpacket该协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
S0CK RAW socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)
SOCK RDM这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包的顺序
protocol:
返回值;
传0表示使用默认协议。
成功:返回指向新创建的socket的文件描述符,失败:返回-1,设置errno
bind函数
#include <sys/types.h>/* See NOTES
#include <sys/socket. h>
int bind (int sockfd. const struct sockaddr *addr. socklen_t addrlen):
sockfd:
socket文件描述符
addr:
构造出IP地址加端口号
addrlen:
返回值:
sizeof (addr)长度
成功返回0,失败返回-1,设置errno,设置的是全局的一个变量,通过查找这个变量找到错误的原因
服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接,因此服务器需要调用bind绑 定一个固定的网络地址和端口号。
bind()的作用是将参数sockfd和addr绑定在一起,使sockfd这个用于网络通讯的文件描述符监听addr所描述的地址和端口号。前面讲过,struct sockaddr, * 是一个通用指针类型,addr参数实际上可以接受多种协议的sockaddr结构体,而它们的长度各不相同,所以需要第三个参数addrlen指定结构体的长度。如:
struct sockaddr_in servaddr:
bzero (&servaddr, sizeof (servaddr));
servaddr. sin_family = AF_INET:
servaddr. sin addr. s addr = htonl(INADDR_ANY);
servaddr. sin port = htons (6666)
首先将整个结构体清零,然后设置地址类型为AF_INET,网络地址为INADDR_ANY,这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也可能约 定多个IP地址,这样设置可以在所有的IP地址上监听,直到与某个客户端建立了连接时才确定下来到底用哪个IP地址,端口号为6666。
需要记住的一点是bzero (&servaddr, sizeof (servaddr)); 在使用结构体的时候需要对结构体进行清零,防止其他的一些意外情况
listen函数
#include <sys/types.h>/* See NOTES*
#include <sys/socket.h>
int listen(int sockfd. int backlog):
sockfd:
socket文件描述符
backlog:
在Linux系统中,它是指排队等待建立3次握手队列长度
查看系统默认backlog
cat /proc/sys/net/ipv4/tcp max_syn_backlog
典型的服务器程序可以同时服务于多个客户端,当有客户端发起连接时,服务器调用的accept()返回并接受这个连接,如果有大量的客户端发起连接而服务器来 不及处理,尚未accept的客户端就处于连接等待状态,listen()声明sockfd处于监听状态,并且最多允许有backlog个客户端处于连接待状态,如果接收到更多的 连接请求就忽略。listen()成功返回0,失败返回-1。
三次握手 上面的backlog是存储能有几个三次握手,比如设置了128,当第129个客户端将不能进行访问。这个是动态的,当队列里面完成三次握手后,将会accept,会将其从队列中清除出去
accept函数
#include <svs/types.h>/* See NOTES */
#include <sys/socket.h>
int accept(int sockfd. struct sockaddr *addr. socklen_t *addrlen);
sockdf:
socket文件描述符
addr:
传出参数,返回链接客户端地址信息,含IP地址和端口号
addrlen:
传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小 返回值:
成功返回一个新的socket文件描述符,用于和客户端通信,失败返回-1,设置errno
返回一个和客户端进行通信的socket
定义一个结构体sockaddr_in,用于接收客户端的ip地址和端口号,然后也要将整个结构体的大小求出来,将整个大小也即调用者提供的缓冲区addr的长度传入,以避免缓冲区溢出问题,传出的是客户端地址结构体的实际长度(有可能没有沾满调用者提供的缓冲区),注意传入的是一个指针,那么就会可能对其进行修改
connect函数
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd. const struct sockaddr *addr. socklen_t addrlen):
sockdf:
socket文件描述符
addr:
传入参数,指定服务器端地址信息,含IP地址和端口号
addrlen:
传入参数,传入sizeof(addr)大小
返回值;
成功返回0,失败返回-1,设置errno
客户端需要调用connect()连接服务器,connect和bind的参数形式一致,区别在于bind的参数是自己的地址,而connect的参数是对方的地址。connect()成 功返回0,出错返回-1。
错误处理
include <sys/types.h>/* See NOTES*/
#include<sys/socket.h>
int listen(int sockfd,int backlog);
sockfd:
socket文件描述符
backlog:
在Linux系统中,它是指排队等待建立3次握手队列长度
查看系统默认backlog
cat /proc/sxs/net/ipv4/tcp_max_syn_backlog
改变系统限制的backlog大小
vim/etc/sysctl. sont
最后添加
net.core.somaxconn = 1024
net.ipv4.tcp_ max_syn_backlog = 1024
保存,然后执行
sysctl-p
典型的服务器程序可以同时服务于多个客户端,当有客户端发起连接时,服务器调用的accept(返回并接受这个连接,如果有大量的客户端发起连接而服务器来 不及处理,尚未accept的客户端就处于连接等待状态,listen()声明sockfd 处于监听状态,并且最多允许有backlog个客户端处于连接待状态,如果接收到更多的 连接请求就忽略。listen(成功返回0,失败返回-1。
在函数里面设置不行,需要在上述文件中的末尾加上这两句话,然后执行后他会显示生效的内容
出错处理函数
上述几个函数出错的时候都会报到到errno中,因此可以在上述一些函数中加上出错处理函数
#include <errno. h>
#include <string.h>
char *strerror (int errnum);/* See NOTES */
errnum:
传入参数,错误编号的值,一般取errno的值
返回值:错误原因
#include <stdio.h>
#include <errno.h>
void perror (const char *s);/* See NOTES */
S:传入参数,自定义的描述
返回值:无
向标准出错stderr输出出错原因
在一些函数上加上出错处理原因,因为如果出错的话一般都返回-1,因此比如
sock=socket(AF_INET,SOCK_STREAM,0);
if(sock==-1) {
fprintf (stderr, "create socket error, reason: 8s\n", strerror (errno) ) ;
exit(1); //因为如果出错的话,就不能往下走了,所以直接结束
}
对于bind()函数也是同理 但在exit前要关闭sock,即close(sock); 对于exit要包含一个库文件<stdlib.h>
但由于太多重复,因此需要将其归为一个函数
perror_exit(const char *des){
fprintf(stderr,"%s error,reason: %s\n",des,strerror(errno));
//对于下一个函数 可以直接perror(des); 不用上面一行 效果是一样的
exit(1);
}
对于socket
还是需要
if(sock==-1){
perror_exit("create socket");
}
对于bind
if(ret==-1){
perror_exit("create bind");
}
http服务器基础知识
http协议
客户端
有一行请求行 在上图中一一对应 请求方法为get url是demo.html 协议版本http/1.1 然后回车到第二行
下面就是请求头部 键值对表示 每一行为一个键值对
在请求头部完成后 回车空一行 到达请求数据 请求数据不是必须的,如果客户端请求服务器时没有数据也是可以的,对于get一般没有数据,对于post会有请求数据的
服务器端
进行响应的时候 第一行为状态行 后几行是消息报文,然后再用一行隔开 到达响应正文,响应正文就是页面的代码
mini服务器
接收http请求
- 实现按行读取请求头部
- 如果碰到两个连续的回车换行则意味着请求头部的结束
、
并发
线程函数
pthread create函数
创建一个新线程,并行的执行任务。
int pthread create(pthread_t *thread, constpthread attr_t *attr, void *(*start_routine) (void*), void *arg);
返回值:成功:0;失败:错误号。
参数:| I=
pthread_t:当前Linux中可理解为:typedef unsigned long int pthreadt;
参数1:传出参数,保存系统为我们分配好的线程ID
参数2:通常传NULL,表示使用线程默认属性。若想使用具体属性也可以修改该参数。
参数3:函数指针,指向线程主函数(线程体),该函数运行结束,则线程结束。
参数4:线程主函数执行期间所使用的参数。
再接收的时候进行创建线程,将要执行的程序写成一个函数,让这个线程去执行
下面是要执行的功能
mysql数据库
- Access数据库是微软家的,现在已经很少用了
- PostgreSql很少用,在数据分析领域内比较广
- DB2
- Mariadb(Mysql的分支,完全兼容mysql 谷歌和维基百科便是用的这个 这个名字是创始人女儿的名字)
对于Ubuntu安装mysql 详见 Ubuntu18.04 安装MySQL_Weison-CSDN博客_ubuntu 安装mysql
如果使用宝塔安装上了mysql 则不需要再进行安装了 比如下面
检查mysql服务状态
systemctl status mysql.service
显示如下结果说明mysql服务是正常的:
远程使用
首先根用户登录,比如我设置了根用户名是kz,那需要用这个登录 将uroot换为ukz 回车输入密码 注意这个root不是linux的root用户 此外 -u 可以加空格 也可以不加空格
不输密码的话回车会让你输密码
进入
sudo mysql -uroot -p
使用exit 退出mysql
- 数据库存储目录
在一般情况下使用yum安装mysql会在 /var/lib/mysql里面
但如果使用宝塔默认安装的话,应该是在/www/server/mysql里面
2.配置文件
配置文件统一在/etc/my.cnf里面
一些命令
- show databases; 展现所有的数据库
- create database 库名; 创建数据库
- drop database 库名; 删除数据库
- use 库名; 切换数据库
备份 这是运维的重点,以后复习的时候需要会,这里不加以展开
mysql的远程管理工具
分为两大类,B/S C/S
B/S架构是浏览器/服务器 百度网站 有个典型的远程管理工具PMA(phpMyadmin 使用php写的)
C/S架构是客户端/服务器 电脑应用 有个典型的远程管理工具navicat、mysql workbrach 专业版的navicat可以连接mysql和oracle和其他的一些数据库 粉红色的navicat
在使用这些远程管理工具需要开放权限,如果使用宝塔可以直接去找相应的功能
下面介绍使用代码开放访问权限
- 先进入数据库选择mysql数据库 mysql>use mysql;
- 执行sql语句:select host,user from user;
- 将其中的一个记录的host值改为” %“ 表示可以在任何地方登陆 updata user set host='%' where host ="yunpan";
- 刷新权限表或者重启mysql 刷新:mysql>flush privileges; 上述可能在第一步的时候不能使用 不知道为啥
注意事项
mysql不区分大小写,末尾要用分号隔开
网络运维
使用Nginx,其属于轻量级的软件
- 下载软件 首先找到软件的地址,然后在服务器里进行下载 首先到要安装的目录里面 #wget 地址 w网络get得到 从网络中下载
- 解压压缩包
- 进入解压目录 进行安装配置
此时会有报错,如果有异常的话可以不用管,但如果是error就必须处理。此时缺少pcre library 所以需要安装pcre-devel
4.此时重新安装
此时报错缺少zlib库 同样处理 安装zlib-devel
5.重新安装
6. 报找不到路径 ,则加上这个路径
太过于复杂 原视频 黑马程序员最全Linux教程视频(有全套笔记和代码以及视频中所使用到的工具)_哔哩哔哩_bilibili
7.最后make install
8.运行Nginx 先停止Apache ,再运行Nginx
serveice httpd stop
然后
路径即/usr/local/nginx/sbin/nginx 启动命令
重载命令
/usr/local/nginx/sbin/nginx -s reload 进行重载
卸载安装的软件
首先要停止软件,然后 #rm -rf 软件的安装目录
关于LAMP和LNMP和LNMPA
LAMP=Linux+Apache+MySql+PHP
LNMP=Linux+Ngine+MySql+PHP-fpm
LNMPA=Linux+Apache+MySql+PHP+Ngine Ngine代理方式
由于Nginx处理静态页面好 ,Apache处理动态页面好,因此混合着用
在服务器上安装的时候先装php再安装apache
filezilla中文版进行上传文件
下载文件后使用22号端口 然后可以在右侧的栏目中进行选择文件
yum傻瓜式联网安装
虽然yum list没有反应
对于-y要避免用,比如在删除某一个软件的时候,可能级联删除其他的东西
对于Ubuntu不能使用yum,不知道为啥,用wget
下接笔记二
一些异常
- 服务器编写程序后要进行编译,编译完再运行,此外,要杀死所有的有关这个程序以前的进程
- html中用的utf-8 浏览器也会有个,在浏览器属性里面进行设置保证两者要相同
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战