《UNIX網絡編程》 -- 第五章
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
char * fgets ( char * str, int num, FILE * stream );
Get string from stream
Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str.
A terminating null character is automatically appended after the characters copied to str.
Notice that fgets is quite different from gets: not only fgets accepts a stream argument, but also allows to specify the maximum size of str and includes in the string any ending newline character.
Parameters
str
Pointer to an array of chars where the string read is copied.
num
Maximum number of characters to be copied into str (including the terminating null-character).
stream
Pointer to a FILE object that identifies an input stream.
stdin can be used as argument to read from the standard input.Return Value
On success, the function returns str.
If the end-of-file is encountered while attempting to read a character, the eof indicator is set (feof). If this happens before any characters could be read, the pointer returned is a null pointer (and the contents of str remain unchanged).
If a read error occurs, the error indicator (ferror) is set and a null pointer is also returned (but the contents pointed by str may have changed).
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
The C library function void perror(const char *str) prints a descriptive error message to stderr. First the string str is printed, followed by a colon then a space.
void err_sys(const char* x) { perror(x); exit(1); }
為什麽 Readline 返回 0 就說明對方關閉了連接呢?
read 當 EOF 時等於 0,因為 EOF 說明接下來沒有數據可以讀了。
In computing, end-of-file (commonly abbreviated EOF) is a condition in a computer operating system where no more data can be read from a data source.
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 服務器進程終止
不明白:(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秒。
The duration that this endpoint remains in this state is twice the maximum segment lifetime (MSL), sometimes called 2MSL
from: 2.7 TIME_WAIT State
沒弄懂。
為什麽二進制會返回空字節?
5.4 殺掉服務器子進程之後,客戶向服務器發送數據導致服務器TCP響應以一個RST。這個RST使得連接中斷,並防止連接的服務器端經歷TIME_WAIT狀態。所以最後兩個分節並不發送。
5.5 重啟服務器進程後,新啟動的服務器看不到之前某個 ESTABLISHED 狀態的數據分節,所以同樣返回 RST。
5.6
不明白 圖5-15,左端數據鏈路與右端的不同。
5.8 數據格式不同,大端與小端。
參考答案:
總結
這章花了很多時間,
一是之前的函數沒有弄懂,倒回去把之前的 readn, writen 弄懂了;
二是習題不會做,原因是麽弄清概念,比如字節序大端和小端,32位和64位,函數修改之後編譯;
《UNIX網絡編程》 -- 第五章