UDP的connect函數

UDP的connect沒有三次握手過程,內核只是檢測是否存在當即可知的錯誤(如一個顯然不可達的目的地),服務器

記錄對端的的IP地址和端口號,而後當即返回調用進程。網絡

 

未鏈接UDP套接字(unconnected UDP socket):新建立UDP套接字默認如此;異步

已鏈接UDP套接字(connected UDP socket):對UDP套接字調用connect的結果。socket

 

對於已鏈接UDP套接字,與默認的未鏈接UDP套接字相比:函數

1)再不能給輸出操做指定目的IP地址和端口號。性能

sendto改用write或send,寫到已鏈接UDP套接字上的任何內容都自動發送到由connect指定的協議地址(如IP地址和端口號)。spa

已鏈接UDP套接字調用sendto,不能指定目的地址。其第五個參數必須爲空指針,第六個參數應爲0或不考慮。指針

2)可不使用recvfrom以獲悉數據報的發送者,改用read、recv或recvmsg。code

在已鏈接UDP套接字上,由內核爲輸入操做返回的數據報只有來自connect所制定協議地址的數據報。blog

這樣就限制一個已鏈接UDP套接字能且僅能與一個對端交換數據報。

3)由已鏈接UDP套接字引起的異步錯誤會返回給它們所在的進程,而未鏈接UDP套接字不接受任何異步錯誤。

POSIX規範指出,在未鏈接UDP套接字上不指定目的地址的輸出操做應該返回ENOTCONN,而不是EDESTADDRREQ。

 應用進程首先調用connect指定對端的IP地址和端口號,而後使用read和write與對端進程交換數據。

來自任何其餘IP地址或端口的數據報不投遞給這個已鏈接套接字,UDP將丟棄它們並生成相應的ICMP端口不可達錯誤。

 

UDP客戶進程或服務器進程只在使用本身的UDP套接字與肯定的惟一對端進行通訊時,才能夠調用connect。

調用connect的一般是UDP客戶,不過有些網絡應用中的UDP服務器會與單個客戶長時間通訊(如TFTP),此時客戶和服務器都有可能調用connect。

DNS客戶、服務器與connect函數的例子:

用於一個已鏈接UDP套接字的進程可出於如下目的之一會再次調用connect:

1)指定新的IP地址和端口號

2)斷開套接字

 

性能:當進程知道本身要給同一個目的地址發送多個數據報時,顯式鏈接套接字效率更高。

而臨時鏈接未鏈接的UDP套接字大約會消耗每一個UDP傳輸三分之一的開銷。

void dg_cli(FILE *fp, int sockfd, SA *pservaddr, socklen_t servlen)
{
    int n;
    char sendline[MAXLINE], recvline[MAXLINE + 1];
    if (connect(sockfd, (SA*)pservaddr, servlen) < 0){
        cout<<"conn error!"<<endl;
        exit(0);
    }
    else
        cout<<"conn succ!"<<endl;

    while (fgets(sendline, MAXLINE, fp) != NULL){
        if (write(sockfd, sendline, strlen(sendline)) < 0){
            cout<<"write error"<<endl;
            exit(0);
        }

        if ( (n = read(sockfd, recvline, MAXLINE)) < 0){
            cout<<"read error"<<endl;
            exit(0);
        }

        recvline[n] = 0;
        fputs(recvline, stdout);

        bzero(sendline, MAXLINE);
        bzero(recvline, MAXLINE);
    }
}
相關文章
相關標籤/搜索