繼續跟著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.使用者體...