str_cli 和 str_echo 函数

需要先弄清楚 3.9 readn、writen 和 readline 函数

str_cli

void
str_cli(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE]; while (Fgets(sendline, MAXLINE, fp) != NULL) { Writen(sockfd, sendline, strlen(sendline)); if (Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("str_cli: server terminated prematurely"); Fputs(recvline, stdout);
}
}

Fgets

fgets

fgets 为 NULL 的情况:

1. read EOF 在有字节读取之前;

2. 发生错误;  

char *
Fgets(char *ptr, int n, FILE *stream)
{
char *rptr; if ( (rptr = fgets(ptr, n, stream)) == NULL && ferror(stream))
err_sys("fgets error"); return (rptr);
}

包裹之后的 Fgets:如果发生错误,调用 err_sys,然后继续返回 rptr。

err_sys

perror

void err_sys(const char* x)
{
perror(x);
exit(1);
}

  

为什么 Readline 返回 0 就说明对方关闭了连接呢?

read 当 EOF 时等于 0,因为 EOF 说明接下来没有数据可以读了。

str_echo

信号处理

Signal(SIGCHLD, sig_chld);

为什么 sig_chld 的 signo 参数没有用到?stat 又是什么?  

#include	"unp.h"

void
sig_chld(int signo)
{
pid_t pid;
int stat; pid = wait(&stat);
printf("child %d terminated\n", pid);
return;
}

5.12 服务器进程终止

《UNIX网络编程》 -- 第五章-LMLPHP

《UNIX网络编程》 -- 第五章-LMLPHP

  不明白:(7) 中说明了,由于客户进程之前接收了 FIN,所以 readline 返回 0。为什么在小字中,还会读取到 RST?

习题

5.1 查看机器的 MSL

对于 MacOS 系统,通过 sysctl net.inet.tcp 系统 tcp 的各种设置。对于 msl,使用

$ sysctl net.inet.tcp | grep msl
net.inet.tcp.msl: 15000

 表示这台机器上的 msl 是 15000 毫秒,即 15秒。

然后,TIME_WAIT 的时间是 2*msl,即 30秒。

《UNIX网络编程》 -- 第五章-LMLPHP

《UNIX网络编程》 -- 第五章-LMLPHP

没弄懂。

为什么二进制会返回空字节?

《UNIX网络编程》 -- 第五章-LMLPHP

《UNIX网络编程》 -- 第五章-LMLPHP

5.4 杀掉服务器子进程之后,客户向服务器发送数据导致服务器TCP响应以一个RST。这个RST使得连接中断,并防止连接的服务器端经历TIME_WAIT状态。所以最后两个分节并不发送。

5.5 重启服务器进程后,新启动的服务器看不到之前某个 ESTABLISHED 状态的数据分节,所以同样返回 RST。

《UNIX网络编程》 -- 第五章-LMLPHP

5.6《UNIX网络编程》 -- 第五章-LMLPHP

《UNIX网络编程》 -- 第五章-LMLPHP

《UNIX网络编程》 -- 第五章-LMLPHP

不明白 图5-15,左端数据链路与右端的不同。

5.8 数据格式不同,大端与小端。

参考答案:

《UNIX网络编程》 -- 第五章-LMLPHP

《UNIX网络编程》 -- 第五章-LMLPHP

总结

这章花了很多时间,

一是之前的函数没有弄懂,倒回去把之前的 readn, writen 弄懂了;

二是习题不会做,原因是么弄清概念,比如字节序大端和小端,32位和64位,函数修改之后编译;

05-02 13:54