天天看點

udp調用connect有什麼作用?使用or不使用connect函數的udp差別多次調用connect



1:UDP中可以使用connect系統調用

2:UDP中connect操作與TCP中connect操作有着本質差別.TCP中調用connect會引起三次握手,client與server建立連結.UDP中調用connect核心僅僅把對端ip&port記錄下來.

3:UDP中可以多次調用connect,TCP隻能調用一次connect.UDP多次調用connect有兩種用途:1,指定一個新的ip&port連結.2,斷開和之前的ip&port的連結.指定新連結,直接設定connect第二個參數即可.斷開連結,需要将connect第二個參數中的sin_family設定成 AF_UNSPEC即可.

4:UDP中使用connect可以提高效率.原因如下:普通的UDP發送兩個封包核心做了如下:#1:建立連結#2:發送封包#3:斷開連結#4:建立連結#5:發送封包#6:斷開連結

采用connect方式的UDP發送兩個封包核心如下處理:#1:建立連結#2:發送封包#3:發送封包另外一點,每次發送封包核心都由可能要做路由查詢.5:采用connect的UDP發送接受封包可以調用send,write和recv,read操作.當然也可以調用sendto,recvfrom.調用sendto的時候第五個參數必須是NULL,第六個參數是0.調用recvfrom,recv,read系統調用隻能擷取到先前connect的ip&port發送的封包.

UDP中使用connect的好處:1:會提升效率.前面已經描述了.2:高并發服務中會增加系統穩定性.原因:假設client A 通過非connect的UDP與server B,C通信.B,C提供相同服務.為了負載均衡,我們讓A與B,C交替通信.A與 B通信IPa:PORTa <----> IPb:PORTbA與 C通信IPa:PORTa' <---->IPc:PORTc

假設PORTa與 PORTa'相同了(在大并發情況下會發生這種情況),那麼就有可能出現A等待B的封包,卻收到了C的封包.導緻收報錯誤.解決方法内就是采用connect的UDP通信方式.在A中建立兩個udp,然後分别connect到B,C.

connect函數不止作用與tcp連接配接,同樣可以作用于udp連接配接.不過兩者的作用不同.

tcp與udp的connect不同

tcp使用connect函數,用戶端發起三次握手協定,在收到對端的确認ack和ack後傳回.對端在收到用戶端的确認ack後,accept傳回.

udp使用connect函數,并沒有發起三次握手協定(這本身就是tcp協定内容),核心會記錄目的端的ip和port,如果本地沒指定port話,核心會自動指定一個port.調用connect,并不會使udp建連.

以下轉自http://blog.csdn.net/cdhql/article/details/42081029

使用or不使用connect函數的udp差別

原理:

無連接配接的udp

socket----->sendto()或recvfrom()

連接配接的udp(使用了connect) 

socket----->connect()----->send()或recv(),read/write.(此時sendto,recvfrom仍可用)

性能:

未連接配接udp套接字上調用sendto時,核心暫時連接配接該套接字,發送資料包,然後斷開連接配接.執行下面的步驟.

未連結UDP套接字:

1.連結套接字

2.輸出第一個資料包

3.斷開套接字

4.連結套接字

5.輸出第2個資料包

6.斷開套接字

已連結套接字

1.連接配接套接字

2.輸出第一個資料包

3.輸出第2個資料包.

n.斷開套接口..

使用connect的變化

1.會傳回異步錯誤給應用程序。

為什麼調用connect後,會收到傳回異步錯誤? 

1)不管是否調用connect,對端關閉時,核心都會收到錯誤之前性能看,每次關閉,核心收到錯誤不知道向誰發送.

2)使用connect核心保持着相關套接字,會向相關套接字發送消息.最明顯的就是每次未連接配接的udp使用sendto會向核心拷貝兩次,而連接配接的udp,即使調用read和write都可以發送,由核心保證目的位址.當核心收到錯誤時,知道向誰傳遞這個錯誤.

3)這個錯誤形式是什麼?icmp消息封包.傳回udp port xxxx unreachable.正如1)所說,不論是否調用connect,核心都會收到icmp的錯誤消息包,對于調用connect的udp程式,read/recvfrom收到的錯誤,errno=111,ECONNREFUSED,解釋為Connection refused.

2.發送:從調用connect以後就可以不使用recvfrom和sendto函數,可以用read和write函數替代.上一步所說由核心儲存目的位址.

3.接收:沒有連結的UDP套接口将會接受所有發送到綁定端口的資料(任何一個程序隻要向UDP綁定端口發送資料,都會被沒有連結的UDP套接口接受),已連結套接口隻會接受連結的另一方的資料,不接受其它人發送過來的資料.當connect時隻能接收目的端ip的資料.

4.已連接配接的udp套接字還可用來确定某個特定目的地的外出接口.由connect用到udp的一個副作用造成的.:核心選擇本機ip位址(多個ip時,且未調用bind顯示綁定).本地ip通過為目的ip搜尋路由表獲得外出接口以及標明接口主ip位址.

多次調用connect

一般有2個目的

1.為套接字指定新的IP和端口号

2.斷開套接字.設定要連結的新套接字的位址族為AF_UNSPEC即可。這可能會傳回一個錯誤,EAFNOSUPPORT錯誤,沒有關系.斷開套接字連接配接是在已連接配接的套接字隻上.



繼續閱讀