日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

無(wú)法連接到internet怎么解決 無(wú)法連接到internet


無(wú)法連接到internet怎么解決 無(wú)法連接到internet


為了講多路復(fù)用,當(dāng)然還是要跟風(fēng),采用鞭尸的思路,先講講傳統(tǒng)的網(wǎng)絡(luò) IO 的弊端,用拉踩的方式捧起多路復(fù)用 IO 的優(yōu)勢(shì) 。
為了方便理解,以下所有代碼都是偽代碼,知道其表達(dá)的意思即可 。
Let's go
阻塞 IO
服務(wù)端為了處理客戶端的連接和請(qǐng)求的數(shù)據(jù),寫(xiě)了如下代碼 。
listenfd = socket();   // 打開(kāi)一個(gè)網(wǎng)絡(luò)通信端口
bind(listenfd);        // 綁定
listen(listenfd);      // 監(jiān)聽(tīng)
while(1) {
  connfd = accept(listenfd);  // 阻塞建立連接
  int n = read(connfd, buf);  // 阻塞讀數(shù)據(jù)
  doSomeThing(buf);  // 利用讀到的數(shù)據(jù)做些什么
  close(connfd);     // 關(guān)閉連接,循環(huán)等待下一個(gè)連接
}
這段代碼會(huì)執(zhí)行得磕磕絆絆,就像這樣 。
可以看到,服務(wù)端的線程阻塞在了兩個(gè)地方,一個(gè)是 accept 函數(shù),一個(gè)是 read 函數(shù) 。
如果再把 read 函數(shù)的細(xì)節(jié)展開(kāi),我們會(huì)發(fā)現(xiàn)其阻塞在了兩個(gè)階段 。
這就是傳統(tǒng)的阻塞 IO 。
整體流程如下圖 。
所以,如果這個(gè)連接的客戶端一直不發(fā)數(shù)據(jù),那么服務(wù)端線程將會(huì)一直阻塞在 read 函數(shù)上不返回,也無(wú)法接受其他客戶端連接 。
這肯定是不行的 。
非阻塞 IO
為了解決上面的問(wèn)題,其關(guān)鍵在于改造這個(gè) read 函數(shù) 。
有一種聰明的辦法是,每次都創(chuàng)建一個(gè)新的進(jìn)程或線程,去調(diào)用 read 函數(shù),并做業(yè)務(wù)處理 。
while(1) {
  connfd = accept(listenfd);  // 阻塞建立連接
  pthread_create(doWork);  // 創(chuàng)建一個(gè)新的線程
}
void doWork() {
  int n = read(connfd, buf);  // 阻塞讀數(shù)據(jù)
  doSomeThing(buf);  // 利用讀到的數(shù)據(jù)做些什么
  close(connfd);     // 關(guān)閉連接,循環(huán)等待下一個(gè)連接
}
這樣,當(dāng)給一個(gè)客戶端建立好連接后,就可以立刻等待新的客戶端連接,而不用阻塞在原客戶端的 read 請(qǐng)求上 。
不過(guò),這不叫非阻塞 IO,只不過(guò)用了多線程的手段使得主線程沒(méi)有卡在 read 函數(shù)上不往下走罷了 。操作系統(tǒng)為我們提供的 read 函數(shù)仍然是阻塞的 。
所以真正的非阻塞 IO,不能是通過(guò)我們用戶層的小把戲,而是要懇請(qǐng)操作系統(tǒng)為我們提供一個(gè)非阻塞的 read 函數(shù) 。
這個(gè) read 函數(shù)的效果是,如果沒(méi)有數(shù)據(jù)到達(dá)時(shí)(到達(dá)網(wǎng)卡并拷貝到了內(nèi)核緩沖區(qū)),立刻返回一個(gè)錯(cuò)誤值(-1),而不是阻塞地等待 。
操作系統(tǒng)提供了這樣的功能,只需要在調(diào)用 read 前,將文件描述符設(shè)置為非阻塞即可 。
fcntl(connfd, F_SETFL, O_NONBLOCK);
int n = read(connfd, buffer) != SUCCESS);
這樣,就需要用戶線程循環(huán)調(diào)用 read,直到返回值不為 -1,再開(kāi)始處理業(yè)務(wù) 。
這里我們注意到一個(gè)細(xì)節(jié) 。
非阻塞的 read,指的是在數(shù)據(jù)到達(dá)前,即數(shù)據(jù)還未到達(dá)網(wǎng)卡,或者到達(dá)網(wǎng)卡但還沒(méi)有拷貝到內(nèi)核緩沖區(qū)之前,這個(gè)階段是非阻塞的 。
當(dāng)數(shù)據(jù)已到達(dá)內(nèi)核緩沖區(qū),此時(shí)調(diào)用 read 函數(shù)仍然是阻塞的,需要等待數(shù)據(jù)從內(nèi)核緩沖區(qū)拷貝到用戶緩沖區(qū),才能返回 。
整體流程如下圖
IO 多路復(fù)用
為每個(gè)客戶端創(chuàng)建一個(gè)線程,服務(wù)器端的線程資源很容易被耗光 。

推薦閱讀