@bit::Shadow
✧(≖ ◡ ≖✿
目录
[设备文件 /dev/null](#设备文件 /dev/null)
[ss -tan | head-n1; ss-tan | grep 8080](#ss -tan | head-n1; ss-tan | grep 8080)
[字段 peer Addres:对端地址](#字段 peer Addres:对端地址)
分号;不论上一个指令执行是否成功均会执行下一个指令
逻辑与符号&&只有当上一个命令执行成功才会执行下一个指令


子进程继承父进程的信号处理动作?像忽略信号动作?
子进程继承父进程的信号处理
是的,子进程会继承父进程的信号处理动作,包括忽略(SIG_IGN)、自定义处理函数和默认行为。这是一个非常重要的特性。
守护进程
cpp
/*守护进程译作:daemon (dei men)*/
const char *workpath = "/";
void Daemon (int cdir, int noclose)
{
//解决IO问题
signal (SIGCHLD, SIG_IGN);
signal (SIGPIPE, SIG_IGN);
if (fork () > 0)
exit (0);
//子进程创建作为新会话组组长
pid_t ret = setsid ();
if(ret < 0)
RETFATAL ("setsid");
//工作路径是否切换?(即守护进程运行的路径)
if(cdir == 0)
chdir (workpath);
// 重定向标准输入、标准输出、标准错误到my.log文件(日志文件)
// 这样做的要求是守护进程特征(默认关闭终端)
if(noclose == 0)
{
int fd = open ("/my.log", O_RDWR);//读写
if(fd < 0)
RETFATAL ("open");
int ret1 = dup2 (fd, 0);
int ret2 = dup2 (fd, 1);
int ret3 = dup2 (fd, 2);
if(ret1 < 0 || ret2 < 0 || ret3 < 0)
RETFATAL ("dup2");
//打开的fd需要关闭吗?--->关闭后会影响写入吗?不会!!!
int ret4 = close (fd);
if(ret4 < 0)
RETFATAL ("close");
}
}
设备文件 /dev/null

凡是写入到这个文件内的内容,均被丢弃。
凡是从该文件读取的内容,均是空。
ss -tan | head-n1; ss-tan | grep 8080
"带表头地"列出当前所有和 8080 有关的 TCP 连接。

第三行四行是因为"本地回环"的原因形成了一对链接。
二、Recv-Q(接收队列)
当前这个 socket 的接收缓冲区里,还有多少字节没被应用层读走。
| 状态 | 含义 |
|---|---|
| LISTEN | 已完成三次握手、但还没被 accept 取走的连接数(backlog 队列里堆积的量) |
| ESTAB | 已收到但应用还没 recv 的数据字节数 |
你的输出:
-
LISTEN的 Recv-Q =0→ 没有积压的未 accept 连接,accept很及时 -
所有 ESTAB 的 Recv-Q =
0→ 没有未读数据,应用读得很干净
如果 LISTEN 的 Recv-Q 持续 > 0,说明
accept太慢或没调用,连接在排队。
三、Send-Q(发送队列)
| 状态 | 含义 |
|---|---|
| LISTEN | listen() 传入的 backlog 值(内核可能截断) |
| ESTAB | 已发给对方但还没收到 ACK 的字节数 |
你的输出:
-
LISTEN的 Send-Q =4→ 你listen()时 backlog 传的是 4(很小,通常传SOMAXCONN即 128 或更大) -
所有 ESTAB 的 Send-Q =
0→ 发出去的数据都被确认了,没有待确认
注意:LISTEN 状态下 Send-Q 不是"待发送数据",而是 backlog。 这是很多人误解的地方。
字段 peer Addres:对端地址
右值=
右值在=右侧是"拷贝进行"的,不是"右值在右"所以没问题

Switch的错误用法
cpp
const int rnum = epoll_wait (_epollfd, _ep, epoll_arr_maxsize, timeout);
switch (rnum)
{
case (bool)(rnum > 0):
/* code */
break;
default:
break;
}
case后必须是"编译期整型常量表达式"。
(bool)(rnum > 0)是运行时计算的值,不是常量。