TCP如何區分監聽套接字和已連線套接字

2021-09-30 08:22:05 字數 1835 閱讀 4382

**

2.10 tcp埠號與併發伺服器

併發伺服器中主伺服器迴圈通過派生乙個子程序來處理每個新的連線。如果乙個子程序繼續使用伺服器眾所周知的埠來服務乙個長時間的請求,那將發生什麼?讓我們來看乙個典型的序列。首先,在主機freebsd上啟動伺服器,該主機是多宿的,其ip位址為12.106.32.254和192.168.42.1。伺服器在它的眾所周知的埠(本例為21)上執行被動開啟,從而開始等待客戶的請求,如圖2-11所示。

圖2-11 tcp伺服器在埠21上執行被動開啟

我們使用記號指出伺服器的套接字對。伺服器在任意本地介面(第乙個星號)的埠21上等待連線請求。外地ip位址和外地埠都沒有指定,我們用"*.*"來表示。我們稱它為監聽套接字(listening socket)。

我們用分號來分割ip位址和埠號,因為這是http的用法,其他地方也常見。netstat程式使用點號來分割ip位址和埠號,不過如此表示有時候會讓人混淆,因為點號既用於網域名稱(如freebsd.unpbook.com.21),也用於ipv4的點分十進位制數記法(如12.106.32. 254.21)。

這裡指定本地ip位址的星號稱為通配(wildcard)符。如果執行伺服器的主機是多宿的(如本例),伺服器可以指定它只接受到達某個特定本地介面的外來連線。這裡要麼選乙個介面要麼選任意介面。伺服器不能指定乙個包含多個位址的清單。通配的本地位址表示"任意"這個選擇。在圖1-9中,通配位址通過在呼叫bind之前把套接字位址結構中的ip位址字段設定成inaddr_any來指定。

稍後在ip位址為206.168.112.219的主機上啟動第乙個客戶,它對伺服器的ip位址之一12.106.32.254執行主動開啟。我們假設本例中客戶主機的tcp為此選擇的臨時埠為1500,如圖2-12所示。圖中在該客戶的下方標出了它的套接字對。

當伺服器接收並接受這個客戶的連線時,它fork乙個自身的副本,讓子程序來處理該客戶的請求,如圖2-13所示。(我們將在4.7節中講解fork函式。)

至此,我們必須在伺服器主機上區分監聽套接字和已連線套接字(connected socket)。注意已連線套接字使用與監聽套接字相同的本地埠(21)。

還要注意在多宿伺服器主機上,連線一旦建立,已連線套接字的本地位址(12.106.32.254)隨即填入。

下一步我們假設在客戶主機上另有乙個客戶請求連線到同乙個伺服器。客戶主機的tcp為這個新客戶的套接字分配乙個未使用的臨時埠,譬如說1501,如圖2-14所示。伺服器上這兩個連線是有區別的:第乙個連線的套接字對和第二個連線的套接字對不一樣,因為客戶的tcp給第二個連線選擇了乙個未使用的埠(1501)。

通過本例應注意,tcp無法僅僅通過檢視目的埠號來分離外來的分節到不同的端點。它必須檢視套接字對的所有4個元素才能確定由哪個端點接收某個到達的分節。圖2-14中對於同乙個本地埠(21)存在3個套接字。如果乙個分節來自206.168.112.219埠1500,目的地為12.106.32.254埠21,它就被遞送給第乙個子程序。如果乙個分節來自206.168.112.219埠1501,目的地為12.106.32.254埠21,它就被遞送給第二個子程序。所有目的埠為21的其他tcp分節都被遞送給擁有監聽套接字的最初那個伺服器(父程序)。

TCP如何區分監聽套接字和已連線套接字???

2010 10 09 10 39 868人閱讀收藏 tcp伺服器 wildcard freebsd socket 2010 2.10 tcp埠號與併發伺服器 併發伺服器中主伺服器迴圈通過派生乙個子程序來處理每個新的連線。如果乙個子程序繼續使用伺服器眾所周知的埠來服務乙個長時間的請求,那將發生什麼?讓...

accept中的監聽套接字和已連線套接字

int accept int sockfd,struct sockaddr cliaddr,socklen t addrlen 該函式用於從已完成連線的佇列隊頭返回下乙個已完成連線。其中sockfd為監聽套接字 cliaddr和addrlen由核心填入客戶端的協議位址 返回值為已連線套接字 乙個服務...

MUD遊戲程式設計 建立TCP監聽套接字

建立tcp監聽套接字 1 建立套接字 int sock socket af inet,sock stream,ipproto tcp 第乙個引數是位址族 address family 第二個引數是套接字型別。sock stream表示tcp套接字。udp使用sock dgram。第三個引數是協議。s...