C網路程式設計socket之connect函式

pengfoo發表於2011-10-24
 網路程式設計socket api存在一批核心介面,而這一批核心介面就是幾個看似簡單的函式,儘管實際上這些函式沒有一個是簡單。connect函式就是這些核心介面的一個函式,它完成主動連線的過程。

   connect函式的功能是完成一個有連線協議的連線過程,對於TCP來說就是那個三路握手過程,它的函式原型:

#include<sys/socket.h>
#include<sys/types.h>
int connect(int sockfd, const struct sockaddr* server_addr, socklen_t addrlen)
返回:0──成功, -1
──失敗。
換一種寫法:
int connect(
    SOCKET s,     // 沒繫結套介面描述字
    const struct sockaddr FAR *name,   // 目標地址指標,目標地址中必須包含IP和埠資訊。
    int namelen   // name的長度
    );

 

 

    為了理解connect函式,我們需要對connect函式的功能進行介紹。connect函式的功能可以用一句話來概括,就是完成面向連線的協議的連線過程,它是主要連線的。面向連線的協議,在建立連線的時候總會有一方先傳送資料,那麼誰呼叫了connect誰就是先傳送資料的一方。如此理解connect三個引數是容易了,我必需指定資料傳送的地址,同時也必需指定資料從哪裡傳送,這正好是connect的前兩個引數,而第三個引數是為第二個引數服務的。

 

引數sockfd
指定資料傳送的套接字,解決從哪裡傳送的問題。核心需要維護大量IO通道,所以使用者必需通過這個引數告訴核心從哪個IO通道,此處就是從哪個socket介面中傳送資料。sockfd是先前socket返回的值。
引數server_addr
指定資料傳送的目的地,也就是伺服器端的地址。這裡伺服器是針對connect說的,因為connect是主動連線的一方呼叫的,所以相應的要存在一個被連線的一方,被動連線的一方需要呼叫listen以接受connect的連線請求,如此被動連線的一方就是伺服器了。
引數addrlen
指定server_addr結構體的長度。我們知道系統中存在大量的地址結構,但socket介面只是通過一個統一的結構來指定引數型別,所以需要指定一個長度,以使核心在進行引數複製的時候有個有個界限。

    與所有的socket網路介面一樣,connect總會在某個時候可能失敗,此時它會返回-1,相應的errno會被設定,使用者可能通過這個值確定是哪個錯誤。常見的錯誤有對方主機不可達或者超時錯誤,也可以是對方主機沒有相應的程式在對應埠等待。

    返回值:沒有錯誤發生,返回0;否則返回SOCKET_ERROR。
    connect函式可用於面向連線套接字,也可用於無連線套接字。
    無連線套接字:對於無連線的套接字(SOCK_DGRAM)
    該套接字與目標地址之間建立預設的對應關係,網路資料互動發生。可以直接使用 send,而不是用sendto來向該地址傳送資料;核心會丟棄所有傳送給該套接字的源地址不是connect 地址的報文。再次呼叫connect函式:此時name和namelen兩個引數均為空指標,就會將該套接字恢復為未連線狀態,再調
用send函式,系統會提示WSAENOTCONN錯誤碼。
    面向連線套接字:面向連線的套接字(SOCK_STREAM),函式connect會引起呼叫端主動進行TCP的三次握手過程。結果通常是成功連線、WSAETIMEDOUT(多次傳送SYN報文,始終未收到回覆)、WSAECONNREFUSED(目標主機返回
TCP-RST)等。

說明:

connect函式將使用引數sockfd中的套接字連線到引數serv_addr中指定的伺服器。引數addrlen為serv_addr指向的記憶體空間大小。

如果引數sockfd的型別為SOCK_DGRAM,serv_addr引數為資料包發往的地址,且將只接收該地址的資料包。如果sockfd的型別為SOCK_STREAM或SOCK_SEQPACKET,呼叫該函式將連線serv_addr中的伺服器地址。

錯誤資訊:

EACCES, EPERM:使用者試圖在套接字廣播標誌沒有設定的情況下連線廣播地址或由於防火牆策略導致連線失敗。

EADDRINUSE:本地地址處於使用狀態。

EAFNOSUPPORT:引數serv_add中的地址非合法地址。

EAGAIN:沒有足夠空閒的本地埠。

EALREADY:套接字為非阻塞套接字,並且原來的連線請求還未完成。

EBADF:非法的檔案描述符。

ECONNREFUSED:遠端地址並沒有處於監聽狀態。

EFAULT:指向套接字結構體的地址非法。

EINPROGRESS:套接字為非阻塞套接字,且連線請求沒有立即完成。

EINTR:系統呼叫的執行由於捕獲中斷而中止。

EISCONN:已經連線到該套接字。

ENETUNREACH:網路不可到達。

ENOTSOCK:檔案描述符不與套接字相關。

ETIMEDOUT:連線超時。

相關文章