UNP讀書筆記第16章 非阻塞IO

2021-08-14 21:51:32 字數 1595 閱讀 8550

繼續跟著steven大佬修改 回射程式

接著第六章的程式

那個程式的大致流程是

先讀輸入,讀完輸入再發給伺服器,接著等伺服器的輸入,並輸出到螢幕上, 總共四個步驟

但是,假如我們一次性輸入的資料非常多,大概有10000行,那麼就會出現一種情況:

當我們正在輸入第5000行時, 第乙個發出去的行,已經被伺服器回射回來了。按理說,這個行應該馬上輸出

但是,他卻會卡在中斷輸入的io那裡(fgets) ,等fgets結束了,才輸出

同理,在輸出到終端時, 本也可以立馬輸入,但是我還是阻塞住了,一直等fputs結束了我才繼續輸入。

顯然這裡的阻塞產生了影響。

所以要想辦法進行分離。

第一種方法: 非阻塞io

將每個描述符設定為非阻塞, 然後設定2個緩衝區, 終端輸入->發出 緩衝區 , 和接收->終端輸出 緩衝區

每當1個緩衝區可讀,或可寫時,從select返回,執行對應的io操作, 並用相應的指標去判斷 是否有資料可發出

是否有資料可終端輸出

第二種方法: 客戶子程序

即客戶fork乙個子程序

父程序用來接收終端輸入,併發送到伺服器上

子程序用來接收伺服器上的資料,並輸出到終端上

當子程序結束後,kill掉父程序,避免伺服器程序提前結束,但父程序不知道的情況。

第一種方法的例程如下,我自己照著敲了一遍, 加了注釋, 順便試著和第六章的程式實驗對比了一下

果然對於輸入大檔案,其速度加快了一倍之多。

#include "unp.h"

#include void str_cli(file *fp, int sockfd)else if (n == 0)else

} if (fd_isset(sockfd, &rset))else if (n == 0)else

} //想輸出到螢幕??先看看給你存的那些伺服器發來的資料夠不夠

//伺服器的資料都給你發完了?說明那邊堵住了,你別急著寫,先歇著!

if (fd_isset(stdout_fileno, &wset) && ((n = friptr - froptr) > 0))else

} //我要往伺服器發資料!先看看內容夠不夠。。。

if (fd_isset(sockfd, &wset) && ((n = toiptr - tooptr) > 0))else

}} } }

int main(int argc, char **argv)

sockfd = socket(af_inet, sock_stream, 0);

bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family = af_inet;

servaddr.sin_port = htons(serv_port);

inet_pton(af_inet, argv[1], &servaddr.sin_addr);

connect(sockfd, (sa *) &servaddr, sizeof(servaddr));

str_cli(stdin, sockfd);

exit(0);

}

UNP讀書筆記第二章

unp讀書筆記第二章 傳輸層 tcp udp sctp 1.使用者資料報協議udp tcp是乙個位元組流服務,udp是無連線的,udp客戶和伺服器之間不存在任何長期的關係 2.傳輸控制協議tcp tcp是可靠地,傳送對端乙個資料時要求對端必須返回確認tcp提供流量控制 tcp的連線是全雙工的 3.六...

UNP讀書筆記第三章

網路位元組序和主機位元組序大小端不一樣。linux提供了4個轉換函式 include uint16 t htons uint16 t value uint32 t htonl uint 32t value uint16 t ntohs uin16 t value uint32 t ntohl uin...

第1 2 16章讀書筆記

第一章 概論 原文 乙個好的軟體,即使功能和同類軟體區別不大,但卻會讓人感覺到非常好用。這就是軟體的使用者體驗。使用者體驗和資料結構,演算法沒有直接的關係,但是很多非常成功的軟體就贏在這個方面。軟體還要處理 不同語言,不同地區的使用者對介面和功能的不同需求,這個叫做軟體的國際化和本地化。1.使用者體...