1,什么是系统调用?
我们如何能让计算机做事情? 人 shell 计算机
人 系统调用 计算机
系统调用:是操作系统提供的某些功能的接口(函数)
系统调用与标准c的区别?
windows程序为什么不能在Linux中执行?
windows程序使用的是windows操作系统所提供的系统调用+windows所提供的编译工具
Linux开发程序:Linux提供的系统调用+Linux提供的编译工具
---------------------------------------------------------------------------
| |
| 用户空间 |
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
| 标准C提供的函数 |
---------------------------------------------------------------------------
|Linux系统调用 |windows系统调用 |
|- - - - - - - - - - - - - - - - - |- - - - - - - - - - - - - - - - - |
|Linux |windows |
| | |
---------------------------------------------------------------------------
| 驱动 | 驱动 |
|- - - - - - - - - - - - - - - - - |- - - - - - - - - - - - - - - - - |
| 硬件 |
| | |
---------------------------------------------------------------------------
Linux系统调用:文件操作 所有文件(普通文件+特殊文件)
文件打开:open
文件操作: 读 写
read write
文件关闭:close
open(文件名,打开文件方式)
文件名:绝对路径、相对路径
打开方式: O_RDONLY(只读)O_WRONLY(只写) O_RDWR(读写的方式)
其他的方式O_APPEND(追加的方式)O_CREAT(创建文件)O_TRUNC(将文件截断为0)
例如:O_WRONLY|O_APPEND
open(文件名,打开方式(O_CREAT),权限)
权限:0666
返回值:文件描述符(成功>0,失败-1)
例如:打开一个文件以只写的方式打开,如果文件存在,则截断为0,如果文件不存在则创建。
w+
open("file", O_WRONLY|O_TRUNC|O_CREAT,0666);
read(文件描述符,地址,字节数)
文件描述符:open函数的返回值(用于读操作的文件)
地址:用于保存字符串的地址
字节数:想要一次读到的字节个数
返回值:成功返回实际读到的字节数,失败:返回0(文件结尾)-1(读出错)
write(文件描述符,地址,字节数)
文件描述符:open函数的返回值(用于写操作的文件)
地址:写入内容的地址
字节数:写入内容的字节数
返回值:成功返回实际写入的字节数,失败:返回0-1
close(文件描述符)
文件描述符:open函数的返回值
练习:
1,编程实现,显示file文件的内容!(使用Linux提供的系统调用)
2,编程实现,统计file文件的大小!
3,编程实现,统计file文件的行数!
例如:char buf[] = "hello\n123\nxyz\nabcd\nppppppoiu\n";
如何统计'\n'的个数?
34 int con_line(char *ptr){
35 int num = 0;
36 char *p = ptr;
37 while(p = strchr(p, '\n')){
38 p+=1;
39 num++;
40 }
41 return num;
42 }
练习1:代码!
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <stdio.h>
6 #include <string.h>
7 int main(void)
8 {
9 int fd;
10 char buf[100];
11 int ret;
12 fd = open("file", O_RDONLY);
13 if (fd < 0){
14 perror("open");
15 return 0;
16 }
17 while(1){
18 bzero(buf, sizeof(buf));
19 ret = read(fd,buf, sizeof(buf)-1);
20 if (ret <= 0)
21 break;
22 printf ("%s", buf);
23 }
24 close(fd);
25 return 0;
26
27 }
标准c提供的文件操作: 只能操作普通文件
文件操作:fopen
文件操作: 读 写
一个字符 fgetc fputc
一行 fgets fputs
一段,一块 fread fwrite
文件关闭:fclose
char buf[100];
fread(buf, size,n, fp);
注意:size*n <= sizeof(buf)
fread(地址,每次读字节数,读次数,文件指针);
练习:
编写一个程序实现cp功能!(提示使用fgetc,fputc)14:20
编写一个程序实现cp功能!(提示使用fgets,fputs)14:50
编写一个程序实现cp功能!(提示使用fread,fwrite)15:00
练习:
模拟登录认证程序!
用于认证的文件格式:
用户名:密码
---------------------------------------------------------------------------
|user:123 |
|xiaoming:234 |
|xiaoli:333 |
| |
| |
---------------------------------------------------------------------------
要求:
从键盘获取name和passwd,与用于文件中的信息进行匹配。
如果一致,打印yes,如果不一致,打印no
提示:
linux怎么读文件内容使用字符串处理函数进行字符串操作(strcpy,strcat,strlen,strstr,strcmp)
使用fgets从文件中获取一行!包括'\n'!
注册程序!
用于认证的文件格式:
用户名:密码
---------------------------------------------------------------------------
|user:123 |
|xiaoming:234 |
|xiaoli:333 |
| |
| |
---------------------------------------------------------------------------
要求:
从键盘获取name和passwd,与用于文件中的信息进行匹配(主要比较name)。
如果有那么相同的,打印no,如果没有,将新用户注册到文件中。
提示:
打开文件的方式:读写!
如何获取名字?例如"user:123"如何获取名字"user"
如何把信息写入到文件中?
新用户注册信息是"name:passwd"
如何添加到文件中:fputs!注意:fputs不会自动添加'\n'
gcc编译过程:
1,预处理:将c代码中的预处理命令,进行执行(例如,文件包含,宏替换,条件编译)
预处理命令:#include #define #
#endif
2,编译:将C代码编译生成汇编代码 C语言操作的内存
此时所有的c语法都没有了,转换为汇编代码 汇编语言操作的寄存器
3,汇编:将汇编代码转换为机器码! 机器码:二进制文件
4,链接:将机器码与库代码进行链接! 可执行的二进制文件(ELF)
gcc 常用参数:
-E:预处理阶段
-S:编译阶段
-c:汇编
-o:链接
其他的参数:
-L:增加一条搜路库文件的路径(默认路径/lib)
-I(大i):增加一条搜索头文件的路径(默认路径/usr/include)
-l(小L):指定加载某一个库
-g:在编译过程中增加调试信息
-Wall:在编译过程中增加警告信息
make:是一个命令
Makefile:是一个文件
当执行make命令,查当前目录中是否有Makefile文件,如果有则执行文件中的功能!
Makefile:做库代码,完成一个项目(多代码,多目录)
将项目生成过程写入到Makefile文件中。调用make命令。
vim编辑器 make(Makefile(vim编译过程)) 类似批处理
Makefile文件语法格式:
目标:依赖文件
命令1
命令2
命令n
自定义变量:
变量名=值
特殊变量:
$@(目标名称) $<(第一个依赖文件) $^(所有依赖文件,不包含重复的)
Linux网络编程:
网络基础:
1,协议?TCP/IP协议
两台计算机如何通讯?windows主机与Linux主机它们如何通讯的?
先协商好一个协议?
美国人 交流(协商:统一一个语言) 中国人
计算机 交流(TCP/IP) 计算机
安装操作系统+网络协议(TCP/IP)
2,TCP/IP(许多协议组成)
传输层:TCP与UDP
tcp协议复杂(慢) udp协议简单(快)
三次握手(数据连接之前,建立连接) 没有三次握手的机制
稳定的,安全的 不稳定
端口号:用来区分应用程序,实现一台主机提供多种服务。
1024以下为公共端口!自定义服务器端口一般在1024以上。
IP:IP地址:用来区分计算机
ip地址:32位二进制数! 为了人操作方便:“点分十进制”
ip地址的组成:网络ID+主机ID
子网掩码:区分IP地址中的网络ID
套接字:IP+端口
虚拟机网卡的设置:
将虚拟机网卡设置为桥接模式!
Linux系统设置IP地址:
查看IP:ifconfig
eth0:网卡设备名称
IP地址:inet addr:192.168.2.200
配置IP:sudo ifconfig 网卡设备名称 IP地址
例如:sudo ifconfig eth0 192.168.5.46
测试网络连接:ping命令
例如 ping 192.168.5.56
查看本机网络连接状态,查看端口状态:netstat -antl
ftp:文件传输协议
安装ftp服务器
客户端:命令行(ftp命令),windows中的IE
服务器:安装ftp服务器软件(vsftpd)
ssh:
安装ssh服务器
客户端:ssh(远程连接),scp(远程拷贝的程序)
服务器:ssh服务器程序
练习:
设置自己的虚拟机,ip地址为192.168.5.x的IP地址,并与同学之间测试连通性!
决定:1,服务器所使用的协议(tcp udp)
如果选择TCP协议:
服务器 客户端
socket(); socket();
bind();
listen();
accpet(); connect();
read/write; write/read;
server.c代码示例:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 6688
int main(void)
{
int sfd; //sfd是服务器调用socket的返回值,用于监听客户端请求
int connfd; //connfd是accept的返回值,用于与客户端传输数据
struct sockaddr_in host; //host是服务器信息(本机IP地址,本机端口号)
/*
socket函数,用于创建用户客户端请求的socket文件描述符。
AF_INET:选择使用IPV4版本
SOCK_STREAM:选择使用TCP协议
0:使用默认协议号
*/
sfd = socket(AF_INET, SOCK_STREAM, 0);
//添加本机信息(协议,IP,端口)
host.sin_family = AF_INET; //添加本机信息:协议
host.sin_addr.s_addr = INADDR_ANY; //添加本机信息:IP
host.sin_port = htons(PORT); //添加本机信息:端口号
/*
bind:将本机信息,与sockfd进行绑定。
sfd:socket文件描述符(socket函数返回值)
(struct sockaddr *)&host:本机信息(其中包含:协议,IP,端口)
sizeof(host):结构体大小。
*/
bind(sfd, (struct sockaddr *)&host, sizeof(host));
/*
listen:将socket文件描述符设置为监听状态。
sfd:socket文件描述符(socket函数返回值)
20:队列长度(最大并发连接数)
*/
listen(sfd, 20);
/*
accept:以阻塞的方式,等待客户端的链接。
sfd:socket文件描述符(socket函数返回值)
注意:后两个参数用于保存客户端信息(如果不关心,可以写为NULL)
connfd:accept返回值,用于与客户端进行数据传输的文件描述符。
如果连接成功,便可以进行数据通信!
*/
connfd = accept(sfd, NULL, NULL);
//向connfd发送数据,即给客户端发送数据。
//read(connfd)/write(connfd);
write(connfd, "hello\n", 7);
//关闭socket文件描述符
close(sfd);
//结束程序
return 0;
}
client.c代码示例:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdio.h>
#define SERVER_IP "服务器IP地址" //服务器IP地址
#define SERVER_PORT 6688 //服务器端口号
int main(void)
{
int sockfd; //客户端socket函数返回值,用于传输请求和数据
struct sockaddr_in server; //用于保存服务器信息(协议,IP,端口)
char buf[100] = ""; //用于保存从服务器读到信息。
/*
socket函数,用于与服务器进行通信的soc
ket文件描述符。
AF_INET:选择使用IPV4版本
SOCK_STREAM:选择使用TCP协议
0:使用默认协议号
*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
//添加服务器信息
server.sin_family = AF_INET; //添加服务器信息:协议
inet_pton(AF_INET, SERVER_IP, &server.sin_addr);//添加服务器信息:ip
server.sin_port = htons(SERVER_PORT); //添加服务器信息:端口号
/*
connect:向服务器发起连接请求。
sockfd:socket函数返回值,用于传输请求与数据。
(struct sockaddr *)&server:服务器信息(包括:协议,IP,端口)
sizeof(server):结构体大小。
*/
connect(sockfd, (struct sockaddr *)&server, sizeof(server));
//从sockfd读取数据(即从服务器读取数据),保存到buf中
read(sockfd, buf, sizeof(buf));
//打印读到的数据
printf ("from server:%s\n", buf);
//关闭sockfd
close(sockfd);
//结束程序
return 0;
}
练习:
1,给上述代码添加相应的头文件与宏定义(能够编译通过)
2,给上述代码添加错误处理!(了解每个系统调用的返回值)
3,给上述代码添加注释!(为每一行添加注释)
Linux多线程:
什么是并发?在某一时刻,做多件事!
单进程,多进程,单线程,多线程?
并发的好处?为什么要实现并发?较多事件的发生!
多进程(fork)
多线程(pthread_create)
线程:轻量级的进程(小进程)
多线程:
创建线程:pthread_create(tid地址, 线程属性,线程函数,线程函数所需参数);
线程退出:pthread_exit();主动推出的方式一般会在线程函数中被调用。类似return
等待线程:pthread_join();等待一个线程结束!实现同步机制时()
线程示例:
1 #include <stdio.h>
2 #include <pthread.h>
3 #include <stdlib.h>
4 void *fun(void *arg);
5 void *fun1(void *arg);
6 int main(void)
7 {
8 pthread_t tid;
9 int a = 10;
10 int b = 20;
11 /*
12 fun();
13 fun1(&a);
14 fun1(&b);
15 */
16 pthread_create(&tid, NULL, fun, NULL);
17 pthread_create(&tid, NULL, fun1, (void *)&a);
18 pthread_create(&tid, NULL, fun1, (void *)&b);
19 sleep(100);
20 return 0;
21 }
22 void *fun(void *arg){
23 while(1){
24 sleep(rand()%3);
25 printf ("fun:hello world\n");
26 }
27 pthread_exit(NULL);
28 }
29 void *fun1(void *arg){
30 int num = *(int *)arg;
31 while(1){
32 sleep(rand()%3);
33 printf ("%d:hello world\n", num);
34 }
35 pthread_exit(NULL);
36 }
编译时:
gcc -o abc pthread.c -lpthread
当使用并发机制的时候!竟
态(竞争某些相同的资源)
使用互斥锁:解决竟态
当使用互斥锁,引发另外的问题:死锁!
解决死锁的:打破产生死锁的条件!
互斥锁初始化pthread_mutex_init()
互斥锁上锁pthread_mutex_lock()
互斥锁判断上锁pthread_mutex_trylock()
互斥锁解锁pthread_mutex_unlock()
消除互斥锁pthread_mutex_destroy()
类似聊天室:
1,如何解决一个客户端退出,服务器也停止?signal(SIGPIPE, SIG_IGN);
2,当一个客户端推出,另外一个客户端死循环?判断read的返回值,设置connfd!
项目名称:聊天室
项目功能:
1,实现远程登录认证
2,实现远程注册
3,实现聊
4,实现私聊
5,实现查看在线用户
附加功能:
1,添加管理员
2,保存聊天记录
讨论问题:
1,服务器要做什么?
2,客户端做什么?
3,是否使用多线程?
4,传输消息,消息的格式是什么样的?
5,采用什么样的数据结构(保存在线用户的信息,以及对应的文件描述符)
M10AC-10L11-48280-032AM-AD26G
YV3RA-FPD00-080YQ-5QPGE-Q68X2
CV7RR-D4XEH-4844Z-C5ZQE-XV884
GU70H-FNG53-080CZ-VFQXT-YGAXA
GY7MH-43F9K-0887Q-UQNNX-XV086
ZZ1WR-6XZ50-48DMP-8PZQZ-XG0E2
VF5X0-44G1P-48E7Y-N5YQE-PZ09F
FU74U-ATZ12-M89AY-LYNZV-NGHG0
GA5DH-8AEE4-H8EFZ-0MMNX-X7KDF
FV3WU-2CFD4-H85LQ-VFYNV-ZKUYF
复习:
1,Linux系统调用(Linux api) 标准C库函数
Linux系统调用中文件操作
open write read close lseek
标准C库提供的文件操作:
fopen fgetc/fputc/fgets/fputs/fread/fwrite fclose fseek
2,
gcc make/makefile
网络基础 Linux系统中如何配置网络
Linux网络编程
如果TCP服务器 socket/bind/listen/accept/读写操作
如果TCP客户端 socket/connect/读写操作
3,多线程
pthread_create pthread_exit pthread_join
项目:聊天室!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论