示例代码 :
server.c
删除到 41 行
d + 41 + 大写 G
示例代码 :
server.c
删除到 41 行
d + 41 + 大写 G
作业 : 实现 socket connect timeout 函数
示例代码 : tcp_client.c
:vsplit tcp_client.h
man connect
man getsockopt : 强制关闭 地址重用
参考网站
https://blog.csdn.net/u012398613/article/details/51914596
扩展思考
当网络条件不好,连接远程服务器时,快捷键的组合可能会被拆开,被拆开是因为什么引起的?
netstat -alnt
ctrl + z
示例代码截屏
man select | cat -n
man select | cat -n | head -n +249 | tail -n +214 | cut -c 15-
select 的例子
示例代码 : select.c
设置粘贴
:set paste
问题 1
终端操作对于输入 标准 IO 是行缓冲的,没有按回车之前数据在标准 IO 的输入缓冲区里面;
数据仍然在标准 IO 的输入缓冲区导致程序结束后再次输出;
问题 2
按回车之后行缓冲机制把数据提交给内核,内核感知数据就绪可读,例子只判断数据可读但是数据没有读,意味着数据还是在标准 IO 的输入缓冲区;
注意
select ( IO 多路复用 ) 感知 IO 变化是一回事,对 IO 操作是另外一回事;
select - IO 多路复用的门槛
man select
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
pselect 是忽略指定信号
阅读手册的 example
IO 多路复用 / IO 多路转接
增加应用程序的并发度 : 在同一个时刻 或 在一个时间段内 能同时响应客户端的数量
多进程的缺陷
1 进程数量
2 代价太高
3 受限于 CPU
4 内存隔离
5 进程间通信代价高
多线程的缺陷
1 受限于 CPU 影响响应能力
2 阻塞 导致响应能力受限
3 非阻塞 要循环检测
多进程和多线程的最大问题是 没有办法感知 IO
IO 多路复用的第一个作用 : 感知 IO ( 感知 IO 是否可读可写或者出错 )
用户 buff
std IO buff
kernel ( 1 回写机制 2 预读操作 )
磁盘文件
kernel 到 文件 涉及以下概念
直接 IO
同步 IO
文件 从用户空间到 标准 IO 空间 到 内核 到 最终磁盘上 的一个往返 ( copy 分 2 次 )
缓冲 IO 的三种机制
non-buffered 无缓冲 -> 标准错误
block buffered 块缓冲 / 全缓冲 - 通常 512 整数倍 -> 文件操作默认块缓冲
line buffered 行缓冲 -> 终端输出
man dd
time dd if=/dev/zero of=./a bs=1 count=2097152
man stdio
stat 函数查看系统 block size
标准 IO 有什么缺陷?两次拷贝影响 IO 效率
① 文件拷贝到内核
② 内核拷贝到用户空间
以上是读,写则相反;
man setbuf - 用 fopen 打开的文件流缓冲 IO 操作
案例 - 管道 pipe
dcy.c
man 2 pipe
man 3 mkfifo
man 3 popen
缓冲 IO
直接 IO
同步 IO
bit mask 比特掩码 : 1 个比特代表一种状态
与 0 或 1
common.c
man ioctl
locate ioctl-types.h
locate ioctls.h
/usr/include/x86_64-linux-gnu/bits/ioctls.h
locate ttydefaults.h
locate features.h
common.c
ioctl(fd, FIONBIO, &ul); ul 为 1 非阻塞 0 阻塞
fcntl(fd, F_SETFL, O_NOBLOCK); 非阻塞
fcntl(fd, F_SETFL, ~O_NOBLOCK); 阻塞
分屏
:vsplit common.h
man fcntl
man 2 open 的 flag 被 F_SETFL 修改
block 阻塞
进程的三态模型 ( 五态 )
1 ready
2 block
3 running
( 4 & 5 进程的开始和结束 )
block 和 挂起 不同
block : 进程需要的资源没有需等 ( 进程状态 )
挂起 : 原先执行现在不执行 把状态保留下来 一直停在这个状态 ( 进程调度 )
IO block 文件阻塞 ( 默认阻塞 )
要的数据还没有被拿到之前等着什么事也不干
非阻塞 IO : send、recv、accept、connect 会直接结束,无法知道 IO 状态,代价是过一会儿一定要回来看看 IO 到底是否做完;
异步 IO ( 非阻塞 IO ) - AIO : 通过系统调用发起一个 IO 操作并且注册一个回调函数 ( 主动告知非询问非等待 );
AIO 最大的问题 : 没有一套在每个系统上都能执行的库;
示例代码 : ls.c - 显示文件列表
在目录里如何操作
readdir()
strcpy(names[cnt++], direntp->d_name);
isatty(STDOUT_FILENO)
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size)
man qsort
动态分配的数组初始化
int len[cnt];
memset(len, 0, sizeof(int) * cnt);
show_files() 显示文件列表
示例代码 : ls.c
在目录里如何操作
readdir()
strcpy(names[cnt++], direntp->d_name);
示例代码 : ls.c
<dirent.h>
<sys/types.h>
opendir()
access()
perror()
示例代码 : ls.c
argc argv optind
ls 命令
opendir()
stat()
示例代码 : ls.c
man 3 getopt
printf : 打印到标准输出
fprintf : 打印到一个文件
```python
111
````