作為bsd unix
的程序通訊
機制,取後一種意思。通常也稱作"套接字"
,用於描述
ip位址
和埠,是乙個通訊鏈的控制代碼。在
internet
上的主機
一般執行了多個服務軟體,同時提供幾種服務。每種服務都開啟乙個
socket
,並繫結到乙個埠上,不同的埠對應於不同的服務。
socket
正如其英文原意那樣,像乙個多孔插座。一台
主機猶如布滿各種插座的房間,每個插座有乙個編號,有的插座提供220
伏交流電,
有的提供
110伏交流電,有的則提供有線電視節目。
客戶軟體將插頭插到不同編號的插座,就可以得到不同的服務。
套接字之間的連線過程可以分為三個步驟:
伺服器監聽,
客戶端請求,連線確認。
伺服器端
套接字並不定位具體的
客戶端套接字
,而是處於等待連線的狀態,實時監控網路狀態。
由客戶端
的套接字
提出連線請求,要連線的目標是
伺服器端的套接字。為此,
客戶端的
套接字必須首先描述它要連線的
伺服器端的套接字,指出
伺服器端套接字的位址和
埠號,然後就向
伺服器端套接字提出連線請求。
當伺服器
端套接字
監聽到或者說接收到
客戶端套接字的連線請求,它就響應
客戶端套接字的請求,建立乙個新的執行緒,把
伺服器端套接字的描述發給
客戶端,一旦客戶端確認了此描述,連線就建立好了。而
伺服器端套接字
繼續處於
監聽狀態
,繼續接收其他
客戶端套接字的連線請求。
進行socket
程式設計的基本函式有
socket
、bind
、listen
、accept
、send
、sendto
、recv
、recvfrom
這幾個,其中對於客戶端和伺服器端以及
tcp和
udp的操作流程都有所區別,這裡先對每個函式進行一定的說明,再給出不同情況下使用的流程圖。
socket
:該函式用於建立乙個
socket
連線,可指定
socket
型別等資訊。在建立了
socket
連線之後,可對
socketadd
或sockaddr_in
進行初始化,以儲存所建立的
socket
資訊。
bind
:該函式是用於將本地
ip位址繫結埠號的,若繫結其他位址則不能成功。另外,它主要用於
tcp的連線,而在
udp的連線中則無必要。
connect
:該函式在
tcp中是用於
bind
的之後的
client
端,用於與伺服器端建立連線,而在
udp中由於沒有了
bind
函式,因此用
connect
有點類似
bind
函式的作用。
send
和recv
:這兩個函式用於接收和傳送資料,可以用在
tcp中,也可以用在
udp中。當用在
udp時,可以在
connect
函式建立連線之後再用。
sendto
和recvfrom
:這兩個函式的作用與
send
和recv
函式型別,也可以用在
tcp和
udp中。當用在
tcp時,後面的幾個與位址有關引數不起作用,函式作用等同於
send
和recv;
當用在udp時,可以用在之前沒有使用
connect
的情況時,這兩個函式可以自動尋找制定位址並進行連線。
伺服器端和客戶端使用
tcp協議的流程圖如圖
10.6
所示。
伺服器端和客戶端使用
udp協議的流程圖如圖
10.7
所示。
網路程式設計中的connect、recv、send都是阻塞性函式,若資源沒有準備好,呼叫這些函式將將進入睡眠狀態,浪費大量不必要的cpu資源。在呼叫accept()、recv()等阻塞性函式,可以使用select函式解決這個問題。
select的機制提供fd_set的資料結構,
實際上是一
long
型別的陣列
,程式設計師將socket控制代碼設定為陣列中的元素,當呼叫select()時,由
核心根據io狀態修改fd_set的內容,由此來通知執行了select()的程序哪一socket或檔案可讀。然後再呼叫相關的函式,如accept()函式等,直接可以處理資料。
以下是關於select()的應用解釋。
int select(nfds, readfds, writefds, exceptfds, timeout)
int nfds;
fd_set *readfds, *writefds, *exceptfds;
struct timeval *timeout;
ndfs:select監視的
檔案控制代碼
數,視程序中開啟的檔案數而定,一般設為你要監視各檔案
中的最大檔案號加一。
readfds:select監視的可讀
檔案控制代碼
集合。
writefds: select監視的可寫
檔案控制代碼
集合。
exceptfds:select監視的異常
檔案控制代碼
集合。
timeout:本次select()的超時結束時間。(見/usr/sys/select.h,可精確至百萬分之一秒!)
返回值:
當返回為-1時,所有描述符集清0。
當返回為0時,超時不修改任何描述符集。
當返回為非0時,在3個描述符集裡,依舊是1的位就是準備好的描述符。這也就是為什麼,每次用select後都要用fd_isset的原因。
以下是關於fd_set的一些用法:
fd_set set;
fd_zero(&set);
fd_set(fd, &set);
fd_clr(fd, &set);
fd_isset(fd, &set);
在將資料寫入乙個
socket
時,盡量一次寫入所有的資料,而不是執行多次寫資料的操作。對於讀操作來說,最好傳入可以支援的最大緩衝區,因為如果沒有足夠多的資料,核心也會試圖填充整個緩衝區(另外還需要保持
tcp的通告視窗為開啟狀態)。這樣,您就可以最小化呼叫的次數,並可以實現更好的整體效能。
其他參考文章:
提高linux
上socket效能
linux
套接字程式設計中的
5個隱患
BNF 鋱可喏 新浪部落格
bnf 以形式化的符號來描述給定程式語言的語法規則。比如 c語言的宣告語句可以用bnf這樣描述 宣告語句 型別 識別符號 型別 識別符號 數字 這一句中 宣告語句 這個非終結符被定義成了兩種形式 上面用 隔開的兩部分 同時在這裡引入了三個終結符 分號 左方括號 右方括號 型別 簡單型別 指標型別 自...
MakeFile使用 鋱可喏 新浪部落格
make 命令執行時,需要乙個 makefile 檔案,以告訴 make 命令如何去編譯和鏈結程式。以下是關於 makefile 使用的幾點總結。l 所有目標檔案的挨個值 l 所有依賴目標的集合。例子 main.out main.o line1.o line2.o g o main.out main...
幀動畫 鋱可喏 新浪部落格
幀動畫稱為drawable animation或者frame animation。l將動畫需要的靜態幀放在res drawable目錄下。l 在res anim目錄下新建resource type為 drawable 並且rootelement為animation list的xml檔案 main 1...