網路程式設計之監聽套接字的誤解

2021-04-29 00:25:29 字數 1276 閱讀 7459

--華清遠見嵌入式學院課堂問題筆記系列

這周同學們在做網路程式設計的時候,碰到乙個監聽套接字的問題,在這裡大概描述一下:

比如我的程式開了乙個監聽埠,與客戶端建立連線之後,生成了乙個新套接字。這時我執行了只關閉監聽埠的語句,結果卻發現監聽埠和已建立的連線仍然存在。我都已經關閉了監聽套接字,為什麼客戶端還可以繼續往監聽埠發資訊?這到底是因為什麼呢?新套接字和監聽套接字有什麼關係呢?

比如,你開了80監聽埠,有乙個客戶連線你accept了,這時關閉80埠。但此時客戶端發資訊的時候必然是發向80斷口,但是80已經關了啊,但是通訊依然正常進行。其實我剛接觸套接字的時候也是認為所有從客戶端發來的資料都需要經過監聽套接字轉一下才能收到。所有的初學者都容易犯這個誤解。

經過一段時間的使用,我現在是明白了,監聽套接字就是個牽線指路的,你實質上是跟它指的那個人說話。因為你要找的那個人不可能隨時等你來,而監聽套接字就是專職等你來問,它回答你要找的人在哪,並喚醒你要找的人,於是通話就建立起來了,就像現實生活中的接線員一樣。

也就是說,在連線建立後,客戶端用發出連線的那個socket向伺服器發資料,是發給伺服器新建立的socket,而不是伺服器的監聽socket。伺服器的監聽socket永遠只是用來接受連線請求。

這就好比你去吃飯,飯館門口有迎賓小姐(監聽socket)看到你來後和你打招呼,然後(accept)找來乙個新的服務員(new socket)來接待你,然後守在門口繼續監聽下乙個。監聽的小姐走了,接待你的服務員當然不受影響。

說到這裡有必要說一下accept()函式。以下是《linux網路程式設計》一書,第六章 berkeley套接字對accept()函式的描述:

函式 accept()有一些難懂。當呼叫它的時候,大致過程是下面這樣的:

● 有人從很遠很遠的地方嘗試呼叫 connect()來連線你的機器上的某個埠(當然是你已經在 listen()的)。

● 他的連線將被 listen 加入等待佇列等待 accept()函式的呼叫(加入等待佇列的最多數目由呼叫 listen()函式的第二個引數 backlog 來決定)。

● 你呼叫 accept()函式,告訴他你準備連線。

● accept()函式將回返回乙個新的套接字描述符,這個描述符就代表了這個連線!

好,這時候你有了兩個套接字描述符,返回給你的那個就是和遠端計算機的連線,而第乙個套接字描述符仍然在你的機器上原來的那個埠上 listen()。

這時候你所得到的那個新的套接字描述符就可以進行 send()操作和recv()操作了。

通過上面的解釋,相信您一定已經對監聽套接字有了進一步的了解了吧!

LINUX網路程式設計之套接字

套接字可以讓linux在網路上通訊,用起來就像管道一樣,當然管道都是單向的,套接字既能寫也能收!以下是多客戶伺服器 include include include include include include include include define port 6000 define size...

套接字程式設計之localsocket

unix domain socket ipc 使用unix domain socket的過程和網路socket十分相似,也要先呼叫socket 建立乙個socket檔案描述符,address family指定為af unix,type可以選擇sock dgram或sock stream,protoc...

Linux 之 網路程式設計之套接字選項

獲取和設定套接字選項 so keepalive選項 so linger選項 so rcvbuf和so sndbuf選項 so rcvlowat和so sndlowat選項 so rcvtimeo和so sndtimeo選項 so reuseaddr選項getsockopt 函式和setsockopt...