erlang之三種socket訊息迴圈

2022-08-10 03:03:16 字數 1786 閱讀 9971

1、主動訊息獲取(非阻塞)

第乙個例子是以主動模式開啟socket,然後接受來自socket的資料:

= gen_tcp:listen(port,[...,...]),

= gen_tcp:accept(listen), loop(socket).

loop(socket) ->

receive

-> ... 輸出處理 ...

-> ...

end.

這個過程無法控制發到伺服器迴圈的訊息流,如果客戶端產生資料的速度大於伺服器消費資料的速度,系統就會收到洪水般地訊息-訊息緩衝區溢位,系統將會crash並表現怪異。

這種型別的伺服器叫做非阻塞伺服器,因為它無法阻塞客戶端。我們僅在信任客戶端的情況下才會使用非阻塞伺服器。

2 被動訊息獲取(阻塞)

在這一節,我們寫阻塞伺服器:伺服器以被動模式開啟socket,通過 選項。這個伺服器不會被危險的客戶端洪水襲擊。

伺服器迴圈中的**呼叫 gen_tcp:recv 來接收資料。客戶端在伺服器呼叫 recv 之前會被阻塞。注意os會對客戶端發來的資料做一下緩衝,以允許客戶端在伺服器呼叫 recv 之前仍然可以繼續傳送一小段資料。

= gen_tcp:listen(port,[...,...]),

= gen_tcp:accept(listen), loop(socket).

loop(socket) ->

case gen_tcp:recv(socket,n) of -> ... 資料處理 ... loop(socket);

...end.

3 混合訊息獲取(部分阻塞)

你可能認為把被動模式用到所有伺服器上都合適。不幸的是,當我們在被動模式時,我們只能等待來自於乙個socket的資料。這對於需要等待多個socket**資料的伺服器則不適用。

幸運的是我們可以用混合方式,既不是阻塞的也不是非阻塞的。我們以一次主動(active once)模式 開啟socket。在這個模式中,socket是主動的,但是只能接收一條訊息。在控制程序發出一條訊息之後,他必須明確的呼叫 inet:setopts 以便讓socket恢復並接收下一條訊息。系統在這發生之前會一直阻塞。這是兩種世界的最好結合點。如下是**:

= gen_tcp:accept(listen), loop(socket).

loop(socket) ->

receive

-> ... 資料處理 ... %%準備好啟用下一條訊息時

inet:setopts(socket,),

loop(socket);

-> ...

end.

使用 選項,使用者可以實現高層次的資料流控制(有時叫交通管制),同時又防止了伺服器被過多的訊息洪水所淹沒。

inet:sockname(socket) 返回本地位址和埠號 }

inet:peername(socket) 返回連線的另一端 位址和埠 }

inet:setopts(sock, ),我們可以讓資料乖乖的聽話,主動發給我們乙個資料,然後變不主動,我們處理完這個訊息後,然後在設定active once,其繼續再發給我們乙個資料. 這樣的好處是,不會因為,給我們傳送了大量的資料,導致我們應接不暇.也不會讓我們每次都手動 gen_tcp:recv/2資料,那麼累人

eclipse erlang外掛程式已經修改為: 

陣列之三種矩陣

矩陣的壓縮 對於某些特殊的矩陣來說,非零元素較少,大部分元素為0,採用某種演算法,將非零元素儲存在一位陣列裡以達到節省儲存空間的目的的過程,稱為矩陣的壓縮 矩陣的還原 將壓縮後的陣列還原成原始矩陣的過程 所謂對角矩陣 矩陣中的所有非零元素都集中在以主對角線為中心的帶狀區域中,即除了主對角線上和直接在...

Kafka之 三種消費模式

以下例項 展示了如何自動提交topic的offset public void autooffsetcommit properties的例項props中存放的key意義 1 bootstrap.servers表示要連線的kafka集群中的節點,其中9092表示埠號 2 group.id表示kafka消...

爬蟲之三種解析方式

1.實現標籤的定位 2.將標籤中的儲存的文字內容或者相關的屬性值進行提取 單字元 除換行以外所有字元 aoe a w 匹配集合中任意乙個字元 d 數字 0 9 d 非數字 w 數字 字母 下劃線 中文 w 非 w s 所有的空白字元包,括空格 製表符 換頁符等等。等價於 f n r t v s 非空...