1. 程式人生 > >監聽套接字 連線套接字的區別

監聽套接字 連線套接字的區別

摘要:對於伺服器程式設計中最重要的一步等待並接受客戶的連線,那麼這一步在程式設計中如何完成,accept函式就是完成這一步的。它從核心中取出已經建立的客戶連線,然後把這個已經建立的連線返回給使用者程式,此時使用者程式就可以與自己的客戶進行點到點的通訊了。

accept函式等待並接受客戶請求:

#include<sys/socket.h>
int accept(int sockfd, struct sockaddr* addr, socklen_t* len)
返回:非負描述字——成功, -1——失敗

accept預設會阻塞程序,直到有一個客戶連線建立後返回,它返回的是一個新可用的套接字,這個套接字是連線套接字。此時我們需要區分兩種套接字,一種套接字正如accept的引數sockfd,它是監聽套接字,在呼叫listen函式之後,一個套接字會從主動連線的套接字變身為一個監聽套接字;而accept返回是一個連線套接字,它代表著一個網路已經存在的點點連線。自然要問的是:為什麼要有兩種套接字?原因很簡單,如果使用一個描述字的話,那麼它的功能太多,使得使用很不直觀,同時在核心確實產生了一個這樣的新的描述字。


引數sockfd
引數sockfd就是上面解釋中的監聽套接字,這個套接字用來監聽一個埠,當有一個客戶與伺服器連線時,它使用這個一個埠號,而此時這個埠號正與這個套接字關聯。當然客戶不知道套接字這些細節,它只知道一個地址和一個埠號。
引數addr
這是一個結果引數,它用來接受一個返回值,這返回值指定客戶端的地址,當然這個地址是通過某個地址結構來描述的,使用者應該知道這一個什麼樣的地址結構。如果對客戶的地址不感興趣,那麼可以把這個值設定為NULL。
引數len
如同大家所認為的,它也是結果的引數,用來接受上述addr的結構的大小的,它指明addr結構所佔有的位元組個數。同樣的,它也可以被設定為NULL。

如果accept成功返回,則伺服器與客戶已經正確建立連線了,此時伺服器通過accept返回的套接字來完成與客戶的通訊。

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

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

比如,你開了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()操作了。

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

相關推薦

連線區別

摘要:對於伺服器程式設計中最重要的一步等待並接受客戶的連線,那麼這一步在程式設計中如何完成,accept函式就是完成這一步的。它從核心中取出已經建立的客戶連線,然後把這個已經建立的連線返回給使用者程式,此時使用者程式就可以與自己的客戶進行點到點的通訊了。 accept函式等

連線

摘要:對於伺服器程式設計中最重要的一步等待並接受客戶的連線,那麼這一步在程式設計中如何完成,accept函式就是完成這一步的。它從核心中取出已經建立的客戶連線,然後把這個已經建立的連線返回給使用者程式,此時使用者程式就可以與自己的客戶進行點到點的通訊了。 accept函式

電話狀態的。響鈴,靜止,

tel mis one iss cal list ack res extend package com.sharpcj.telephonestatelistenerdemo; import android.content.Context; import android.

ORA-12514: TNS: 程序當前無法識別連描述符中請求的服務解決

generate 啟動 port 不同 技術 sid ati 請求 desc 問題:Oracle主服務和監聽器服務已經啟動,使用SQL Plus能夠正常連接,使用PL SQL Developer連接報次錯誤:ORA-12514: TNS: 監聽程序當前無法識別連接描述符中請

oracle11G 已開啟,但遠程連依舊無解決過程

無法 無法啟動 col min 進入 排查 安裝 ner start 1、連接數據庫顯示無監聽程序,首先查看服務器的oracle監聽服務是否開啟,服務名稱:OracleOraDb11g_home1TNSListener(具體環境中可能不完全一樣,但是認準TNSListene

windows 下 PostgreSQL 配置及遠程連

postgresqlPostgreSQL服務端運行在windows上,IP為:192.168.240.128配置方法: 1. 修改服務端文件 你的安裝目錄/postgresql/data/postgresql.conf文件,將 #listen_address=‘localhost‘改成listen_addr

ORA-12505: TNS: 程序當前無法識別連描述符中所給出的SID等錯誤解決方法

RR script 監聽 修改 查詢 listen 註冊 其他 esc 程序連接orarle報ORA-12505錯誤 一、異常{ ORA-12505, TNS:listener does not currently know of SID given in connect

【Oracle】ORA-12514: TNS: 程序當前無法識別連描述符中請求的服務

otto display rod ack rate ron lis 請求 tool 早上使用PL/SQL連接Oracle的時候,報錯如下 解決辦法: 找到文件listener.ora,新增以下紅色區域,註意:路徑需要根據自己的Oracle安裝路徑自行設置 # liste

oracle無程序的解決方法(PLSQL)Oracle ORA12514 程序當前無法識別連描述符中請求的服務

listener 描述 ORC ngs roc 識別 network tor listen \PLSQL\instantclient_11_2 listener.ora # listener.ora Network Configuration File: E:\so

Android利用廣播設備網絡連(斷網)的變化情況

prot create 廣播 ast 例如 ews backup 聲明 flags 版權聲明: https://blog.csdn.net/lfdfhl/article/details/2

oracle11G 已開啟,但遠端連線依舊無解決過程

1、連線資料庫顯示無監聽程式,首先檢視伺服器的oracle監聽服務是否開啟,服務名稱:OracleOraDb11g_home1TNSListener(具體環境中可能不完全一樣,但是認準TNSListener是沒錯的) 2、本地使用127.0.0.1可以連線,但使用本機IP則

Mac OS 下/攔截 TCP/UDP 連線

在開發時,客戶端經常需要發起web service呼叫或訪問http資源,但無法看到發出的 http 報文,這為除錯帶來苦難。通過下面這個命令,能開啟一個攔截程序,本機特定埠的 TCP/UDP 連線都會被攔截,並看到訊息內容。 nc -l localhos

Uiautomator2網路狀態,連線指定Wi-Fi

工作中接觸到uiautomator測試框架,從1.0到2.0,改動還是挺大的,1.0是以jar的形式push到手機中,主要是已Eclipse開發為主,到了2.0則是以apk形式安裝到手機中,主要是以Android Studio開發為主,個人感覺還是2.0要強大,而且方便一些。

[實驗]關閉TCP對已建立連線的影響

先說結果吧,結果是無影響,已建立的連線依然可以正常使用。 實驗環境 windows10,vs2010 實驗過程 伺服器採用VC程式設計,客戶端使用TCP除錯軟體。 伺服器工作流程 1、建立監聽套接字socket1,繫結埠17000。 2、使用listen函式監聽

accept中的和已連線

int accept(int sockfd, struct sockaddr* cliaddr, socklen_t *addrlen); 該函式用於從已完成連線的佇列隊頭返回下一個已完成連線。 其中sockfd為監聽套接字 cliaddr和addrlen由核心填入

TCP如何區分和已連線???

2.10 TCP埠號與併發伺服器 併發伺服器中主伺服器迴圈通過派生一個子程序來處理每個新的連線。如果一個子程序繼續使用伺服器眾所周知的埠來服務一個長時間的請求,那將發生什麼?讓我們來看一個典型的序列。首先,在主機freebsd上啟動伺服器,該主機是多宿的,其IP地址為12.106.32.254和192.1

在io複用中把設為非阻塞

  往往在select 或 epoll 中把 listen_socket 設定為非阻塞 O_NONBLOCK 原因是出在 accept 上, 比如有這麼一個客戶端 : RST客戶端 當這個select或epoll 的伺服器非常繁忙時, 有這麼一個一連線就斷開的客戶端,

epoll中的觸發模式

我們知道epoll有兩種觸發模式:水平觸發(LT)和邊緣觸發(ET) LT模式 若資料可讀,epoll返回可讀事件 若開發者沒有把資料完全讀完,epoll會不斷通知資料可讀,直到資料全部被讀取。 若socket可寫,epoll返回可寫事件,而且

用原始實現網路

 作者:張志強 下載原始碼 1、引言    網路監聽工具(sinff)是提供給網路管理員的一類管理工具。在乙太網中(Ethernet),當網路上連線多臺計算機時,某瞬間只能有一臺計算機可以傳送資料。乙太網中,資料是以被稱為幀的資料結構為單位進行交換的。通常,在計算機網路上交換

linux epoll例項

linux epoll機制用於IO多路複用,能夠同時監聽多個接字,使用起來比較簡單。相關介面: #include <sys/epoll.h> int epoll_create(int size); int epoll_cr