1. 程式人生 > >《UNIX網絡編程》 -- 第五章

《UNIX網絡編程》 -- 第五章

!= fun ati err unp led des com const

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網絡編程》 -- 第五章