Linux網路程式設計讀書筆記 7

2021-03-31 11:21:31 字數 4357 閱讀 9177

第九章高階套接字函式程式設計

·

9.1

傳送和接收函式的高階用法

標頭檔案:

, int send(int sockfd, void *buf, int len, int flags);

[flags=msg_oob, msg_dontwait, msg_dontroute]

int recv(int sockfd, void *buf, int len, int flags);

[flags=msg_oob, msg_peek, msg_waitall, msg_dontroute]

標頭檔案:

int readv(int fd, struct iovec *iov, int iovlen);//

將套接字緩衝區資料讀到多個應用緩衝區中

int writev(int fd, struct iovec *iov, int iovlen);//

將多個應用緩衝區寫到套接字緩衝區資料中

struct iovec;

標頭檔案:

, int recvmsg(int sockfd, struct msghdr *msg, int flag);//

常用在unix

域套接字中對

int sendmsg(int sockfd, struct msghdr *msg, int flag);//

程序間傳送

/接收檔案描述符使用

struct msghdr;

使用這兩個函式傳送附加訊息時候通常需要定義以下結構體:

union;

操作巨集,標頭檔案

: ,

struct cmsghdr *cmsg_firsthdr(struct msghdr *msghdrptr);//

指向第乙個

cmsghdr

結構指標

struct cmsghdr *cmsg_nexthdr(struct msghdr *msghdrptr, struct cmsghdr *cmsgptr);

unsigned char *cmsg_data(struct cmsghdr *cmsghdr); //

返回指向

cmsghdr

結構第乙個位元組

unsigned cmsg_len(unsigned int lenght);//

獲取cmsghdr

中存放資料位元組數

第十章守護程序和超級伺服器

i***d

·

10.1

守護程序的原理

只要系統沒有關機或者崩潰,守護程序將在系統中不間斷執行。關鍵是如何把守護程序的執行環境和其他程序的執行環境隔離。步驟:

1 第一次

fork

和setsid

函式呼叫建立新會話組

這個操作的主要目的是為了讓乙個程序和控制終端脫離,這樣來自終端的訊號就不會影響到守護程序。

setsid()

函式的功能是讓建立乙個新的會話過程,並讓呼叫

setsid()

的程序成為該會話過程的領頭程序。但是

setsid()

的呼叫條件是這個程序不是乙個程序組的主程序。因此我們先

fork()

乙個子程序並終止該程序組主程序的執行,在子程序中呼叫

setsid()

讓子程序成為不帶控制終端的新會話過程的領頭程序。於是這個程序就和原控制終端脫離,並成為新會話組的領導程序。

2 第二次

fork

和setpgrp

函式呼叫建立新程序組

呼叫setsid()

之後,雖然在新的會話組中的領導程序不帶控制終端。但是如果這個程序開啟了乙個終端,那麼整個會話組將又重新的控制終端。因此我們需要

fork()

乙個新的子程序繼續執行,並終止該會話組領頭程序的執行。此時這個新程序不是會話組領導程序,所以即使開啟乙個終端也不會成為整個會話組的控制終端。

但由於父程序是會話組的領頭程序,如果讓父程序退出而子程序繼續執行,那麼將傳送

sighup

(中斷和掛起訊號)給這個會話組中所有程序。因此我們要先忽略訊號

sighup

,然後再

fork

,接著退出父程序而子程序繼續執行。

但是這個新程序仍然和已退出父程序同在乙個程序組中,仍然會受到同個程序組中的訊號影響。所以我們要使用

setpgrp()

讓這個程序成為新的程序組的領導者。

3 關閉所有檔案描述符

fork()

時候子程序將繼承父程序的檔案描述符。我們需要在守護程序中關閉先前開啟的檔案描述符,以免對其他程序造成影響。使用

sysconf(_sc_open_max)

函式獲取系統中每個程序可以開啟檔案的最大數目,然後使用

close()

關閉它們。

4 消除

umask

的影響每個程序都有乙個

umask

同它關聯。

umask

指定程序建立檔案的保護掩碼,是系統提供的一種安全機制,限制程序建立檔案的許可權。比如程序建立乙個檔案的許可權為

0777

,程序umask

為0277

,那麼實際檔案許可權為

0777-0277=0500

。此時如果其他程序去讀寫守護程序建立的檔案可能會受到檔案掩碼的影響。使用

umask(0)

系統呼叫清除舊的檔案掩碼。

5 改變守護程序的當前目錄

每個程序都有乙個當前目錄,當程序產生錯誤時可以將錯誤資訊記錄在當前目錄的

core

檔案中供以後分析錯誤使用。如果不把守護程序修改到乙個安全的目錄,那麼守護程序的當前目錄是不確定的,並可能影響到其他系統的管理工作。我們可以使用

chdir(「/」);

將守護程序當前目錄修改到根目錄下。

6 對標準

i/o描述符重定向

由於守護程序不連線任何控制終端,並且所有檔案描述符都關閉。那麼如果意外呼叫

printf, perror

等輸出將導致出錯。我們把標準

i/o重定向到無傷害裝置

(harmless device)

描述符上,那麼對標準

i/o的操作都將忽略避免人為意外使用出錯。

7 使用

syslog

記錄守護程序的錯誤

syslogd

本身就是乙個守護程序,使用

udp 514

埠。應用程式可以傳送

udp報文記錄錯誤資訊。

void syslog(int priority, const char *message, ...); //#incluse

8 檔案鎖和控制守護程序副本互斥執行

為了避免執行多個相同的守護程序產生的干擾,因此使用鎖檔案的方式記錄守護程序的工作情況。

linux

系統的鎖採用諮詢鎖,只是系統將告知檔案鎖定情況而不阻止程序對檔案的操作。我們可以使用

int flock(int fd, int operation); //#include

[operation = lock_sh

共享鎖, lock_ex

互斥鎖,

lock_un

解鎖,lock_nb

程序獲取鎖失敗不堵塞,預設為程序堵塞

] 示例**:

int init_daemon(const char *pathname, int facility);

·10.2

超級伺服器

i***d

的工作原理

由於伺服器套接字初始化方式非常類似,所以可以設計乙個專門的伺服器負責初始化工作,並且它將根據接入埠不同呼叫相應的服務程式進行工作,這些服務程式在未被接入前都處於睡眠等待狀態。採用超級伺服器的方式可以讓伺服器程式採用統一方式管理。

超級伺服器將採用

select

的方式併發檢測在檔案

/etc/i***d.conf

中說明的

tcp/udp

埠,一旦發現有客戶接入就建立乙個子程序。超級伺服器

i***d

是服務接入者,它在建立字程序時候呼叫

exec()

載入具體的服務程式。在子程序中關閉傾聽套接字,父程序中關閉連線套接字,於是父程序繼續檢測,子程序開始為客戶端進行服務。對於

wait

服務程式,超級伺服器

i***

載入它時候將其在檢測集合中刪除,等待該服務結束後才能接入下次服務。服務程式完畢後將傳送

sigchld

訊號,超級伺服器將其繼續加入檢測集合。當系統管理員修改超級伺服器配置檔案後將傳送

sighup

訊號,超級伺服器將重新初始化。

《Linux網路程式設計》讀書筆記

去年買了 linux網路程式設計 這本,沒想到一放就是半年的時間了,慚愧啊!當年的雄心壯志都去哪了 好,廢話不多說,從今天開始,每天積累一點,厚積才能薄發,磨刀不誤砍柴工。工資趕快漲 漲 1991年,linux開始誕生了,到2011年,linux的版本從2.6直接蹦到了3.0,據說這個沒什麼大意義,...

Linux網路程式設計讀書筆記 4

第四章 基本套接字程式設計 4.1 基本套接字函式族 標頭檔案 主要函式 int socket int domain,int type,int protocol 建立socket 描述符 domain af unix,af i af iso type sock stream,sock dgram,s...

Linux網路程式設計讀書筆記 8

第十一章 資料結構的傳輸和 xdr標準 11.1 資料結構的傳送 網路資料結構傳遞可能存在以下問題 網路字序問題 浮點數傳輸 指標處理 自定義手工處理方式 將待傳送資料結構轉換以後放入應用的傳送緩衝區 將應用的接收緩衝區中資料結構轉換以後再進行資料處理。示例 void send int32 2buf...