網路IPC 套接字之建立連線

2021-09-08 17:08:26 字數 2861 閱讀 7040

如果處理的是面向連線的網路服務(sock_stream或sock_seqpacket),在開始交換資料以前,需要在請求服務的程序套接字(客戶端)和提供服務的程序套接字(伺服器)之間建立乙個連線。客戶端可以用connect建立乙個連線。

#include int connect(int sockfd, const

struct sockaddr *addr, socklen_t len);

返回值:若成功則返回0,出錯則返回-1

在connect中所指定的位址是想與之通訊的伺服器位址。如果sockfd沒有繫結到乙個位址,connect會給呼叫者繫結乙個預設位址。

當連線乙個伺服器時,出於一些原因,連線可能失敗。要連線的機器必須開啟並且正在執行,伺服器必須繫結到乙個想與之連線的位址,並且在伺服器的等待連線佇列中應有足夠的空間。因此,應用程式必須能夠處理connect返回的錯誤,這些錯誤可能由一些瞬時變化條件引起。

例項

程式清單16-2顯示了一種如何處理瞬時connect錯誤的方法。這在乙個負載很重的伺服器上很有可能發生。

#include "

apue.h

"#include

#define maxsleep 128

intconnect_retry(

int sockfd, const

struct sockaddr *addr, socklen_t len)

/** delay before trying again.

*/if(nsec <= maxseelp/2

) sleep(nsec);

}return(-1

);}

這個函式使用了名為指數補償(exponential backoff)的演算法。如果呼叫connect失敗,程序就休眠一小段時間後再嘗試,每迴圈一次增加每次嘗試的延遲,直到最大延遲為2分鐘。

如果套接字描述符處於非阻塞模式下,那麼在連線不能馬上建立時,connect將會返回-1,並且將errno設為特殊的錯誤碼einprogress。應用程式可以使用poll或select來判斷檔案描述符何時可寫。如果可寫,連線完成。

函式connect還可以用於無連線的網路服務(sock_dgram)。這看起來有點矛盾,實際上卻是乙個不錯的選擇。如果在sock_dgram套接字上呼叫connect,所有傳送報文的目標位址設為connect呼叫中所指定的位址,這樣每次傳送報文時就不需要再提供位址。另外,僅能接收來自指定位址的報文。

伺服器呼叫listen來宣告可以接受連線請求。

#include int listen(int sockfd, int

backlog);

返回值:若成功則返回0,出錯則返回-1

引數backlog提供了乙個提示,用於表示該程序所要入隊的連線請求數量。其實際值由系統決定,但上限由中somaxconn指定。

一旦佇列滿,系統會拒絕多餘連線請求,所以backlog的值應該基於伺服器期望負載和接受連線請求與啟動服務的處理能力來選擇。

一旦伺服器呼叫了listen,套接字就能接收連線請求。使用函式accept獲得連線請求並建立連線。

#include int accept(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict len);

返回值:若成功則返回檔案(套接字)描述符,出錯則返回-1

函式accept所返回的檔案描述符是套接字描述符,該描述符連線到呼叫connect的客戶端。這個新的套接字描述符和原始套接字(sockfd)具有相同的套接字型別和位址族。傳給accept的原始套接字沒有關聯到這個連線,而是繼續保持可用狀態並接受其他連線請求。

如果不關心客戶端標識,可以將引數addr和len設為null;否則,在呼叫accept之前,應將引數addr設為足夠大的緩衝區來存放位址,並且將len設為指向代表這個緩衝區大小的整數的指標。返回時,accept會在緩衝區填充客戶端的位址並且更新指標len所指向的整數為該位址的大小。

如果沒有連線請求等待處理,accept會阻塞直到乙個請求到來。如果sockfd處於非阻塞模式,accept會返回-1並將errno設定為eagain或ewouldblock。

如果伺服器呼叫accept並且當前沒有連線請求,伺服器會阻塞直到乙個請求到來。另外,伺服器可以使用poll或select來等待乙個請求的到來。在這種情況下,乙個帶等待處理的連線請求套接字會以可讀的方式出現。

例項

程式清單16-3顯示了乙個伺服器程序用以分配和初始化套接字的函式。

程式清單16-3 伺服器初始化套接字端點

#include "

apue.h

"#include

#include

intinitserver(

int type, const

struct sockaddr *addr, socklen_t alen, int

qlen)

if(type == sock_stream || type ==sock_seqpacket)

}return

(fd);

errout:

close(fd);

errno =err;

return(-1

);}

本篇博文內容摘自《unix環境高階程式設計》(第2版),僅作個人學習記錄所用。關於本書可參考:

網路IPC 套接字之建立連線

如果處理的是面向連線的網路服務 sock stream或sock seqpacket 在開始交換資料以前,需要在請求服務的程序套接字 客戶端 和提供服務的程序套接字 伺服器 之間建立乙個連線。客戶端可以用connect建立乙個連線。include int connect int sockfd,con...

網路IPC 套接字

1.套接字是通訊端點的抽象。與應用程式要用檔案描述符訪問檔案一樣,訪問套接字也需要用套接字描述符。套接字描述符在unix系統是用檔案描述符實現的。要建立乙個套接字,可以呼叫socket函式。include int socket int domain,int type,int protocol 返回值...

網路IPC 套接字

套接字描述符 includeint socket int domain,int type,int prootocol 返回值 若成功,返回檔案 套接字 描述符,若出錯,返回 1域 描述af inet ipv4 網際網路域 af inet6 ipv6網際網路域 af unix unix域 af ups...