基於無連接的UDP程序設計
相關閱讀:Linux網絡編程:基於TCP的程序開發回顧篇 http://www.linuxidc.com/Linux/2012-07/65693.htm
同樣,在開發基於UDP的應用程序時,其主要流程如下:
對於面向無連接的UDP應用程序在開發過程中服務端和客戶端的操作流程基本差不多。對比面向連接的TCP程序,服務端少了listen和accept函數。前面我們也說過listen函數最主要的作用就是將一個socket套接字描述符轉為被動監聽模式,然後調用accept主要是用於等待客戶端(用connect)來連接服務器。connect函數不僅可以用於流式套接字還可用於數據報式套接字。在TCP中,客戶端調用connect函數會向服務器端觸發一個TCP的3次握手過程,去建立一條TCP連接;而在UDP中,客戶端調用該函數主要的作用是告訴後面將要調用的recvfrom函數,僅僅只接受在connect函數中指明的服務器發來的數據,這樣當後面調用recvfrom時最後兩個參數就可以置為NULL了。也就說對UDP編程來說,客戶端調用connect是可選的:如果調用了connect函數,recvfrom就可以省掉最後兩個參數;如果不調用connect則recvfrom必須指明從哪兒收數據。
對於UDP的編程其實主要在數據的收發處理上,而面向無連接的UDP編程中收發數據用到的最多的函數就是recvfrom()和sendto(),其原型如下:
ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
ssize_t sendto(int s, const void *buf, size_t len, int flags, struct sockaddr *to, socklen_t tolen);
recvfrom函數主要用於從s所指定的套接字中接收數據,並將其存儲在buf所指向的緩沖區裡。如果from參數不為NULL,那麼其中便會攜帶消息發送端的地址信息,fromlen則指明了信息發送方地址信息結構體的大小。如果接收方對發送發的地址不感興趣,將from和fromlen置為NULL即可。返回值:小於0,有錯誤;大於0,實際收到的字節數;等於0,對端主動關閉。
sendto函數,主要是buf所指向的數據發送到套接字描述符s中,len為要發送的數據長度,to中存儲了對端的地址信息,即數據該發往何處,tolen為to所占的字節數。返回值:小於0,有錯誤;大於0,實際發送的字節數。
另外我們還知道,sendto是可以用於面向連接的流式套接字的,在TCP開發章節我們已經提過。這裡在羅嗦一點,如果sendto用於面向流式的套接字編程中,to和tolen參數都會被忽略,如果發送數據時連接還未建立相應的提示錯誤為ENOTCONN。