天天看點

運用listen()和accept()函數

關于效勞器端程式,運用 bind() 綁定套接字後,還需求運用 listen() 函數讓套接字進入主動監聽形态,再挪用 accept() 函數,就可以随時呼應用戶端的懇求了。

經過 listen() 函數可以讓套接字進入主動監聽形态,它的原型為:

sock 為需求進入監聽形态的套接字,backlog 為懇求隊列的最大長度。

所謂主動監聽,是指當沒有用戶端懇求時,套接字處于“睡眠”形态,隻要當接納到用戶端懇求時,套接字才會被“叫醒”來呼應懇求。

當套接字正在處置用戶端懇求時,假如有新的懇求出去,套接字是沒法處置的,隻能把它放進緩沖區,待以後懇求處置終了後,再從緩沖區中讀掏出來處置。假如不時有新的懇求出去,它們就依照先後次序在緩沖區中列隊,直到緩沖區滿。這個緩沖區,就稱為懇求隊列(Request Queue)。

緩沖區的長度(能寄存若幹個用戶端懇求)可以經過 listen() 函數的 backlog 參數指定,但終究為若幹并沒有什麼規範,可以依據你的需求來定,并發量小的話可是以10或許20。

假如将 backlog 的值設定為 SOMAXCONN,就由零碎來決議懇求隊列長度,這個值普通比拟大,能夠是幾百,或許更多。

當懇求隊列滿時,就不再接納新的懇求,關于 Linux,用戶端會收到 ECONNREFUSED 毛病,關于 Windows,用戶端會收到 WSAECONNREFUSED 毛病。

留意:listen() 隻是讓套接字處于監聽形态,并沒有接納懇求。接納懇求需求運用 accept() 函數。

當套接字處于監聽形态時,可以經過 accept() 函數來接納用戶端懇求。它的原型為:

它的參數與 listen() 和 connect() 是相反的:sock 為效勞器端套接字,addr 為 sockaddr_in 構造體變量,addrlen 為參數 addr 的長度,可由 sizeof() 求得。

accept() 前往一個新的套接字來和用戶端通訊,addr 保管了用戶端的IP位址和端智語,而 sock 是效勞器端的套接字,人人留意辨識。前面和用戶端通訊時,要運用這個重生成的套接字,而不是本來效勞器端的套接字。

最初需求闡明的是:listen() 隻是讓套接字進入監聽形态,并沒有真正接納用戶端懇求,listen() 前面的代碼會持續履行,直到碰到 accept()。accept() 會壅塞程式履行(前面代碼不克不及被履行),直到有新的懇求到來。

繼續閱讀