2010-02-10 64 views
8

我在理解recv()/ recvfrom()從非阻塞UDP套接字返回時遇到問題。在C中的非阻塞udp套接字編程:我得到什麼?

更具體一點,並與TCP(請糾正我,如果我錯了):直到

  • 阻塞套接字(TCP或UDP)將不會從一個recv的返回()有是緩衝區中的一些數據。這可能是一些字節數(TCP)或完整的數據報(UDP)。

  • 一個非阻塞的TCP套接字或者返回EWOULDBLOCK(linux)/ WSAEWOULDBLOCK(windows)或者當前在緩衝區中的字節。由於TCP數據是一個流,返回多少字節並不重要。

現在的問題:

  • 非阻塞UDP套接字也返回WOULDBLOCK(Linux)的/ WSAEWOULDBLOCK(窗口),如果沒有可用數據。但是,如果有數據可用,那麼非阻塞UDP套接字是否只返回一些字節,這可能意味着您只能獲得數據報的一半或者UDP套接字始終返回完整的數據報?

編輯:

我指的是「一個數據包的一半」的是:會發生什麼,如果我可以調用recv()在短短的時刻插座當前正在接收數據報。在那一刻,緩衝區中有一些字節,但數據報尚未完成。

您的解釋和意見,讚賞。謝謝!

回答

8

最後,藉口從我的舊辦公室裏挖出我的史蒂文斯圖書。

如果緩衝區足夠大,標準伯克利插座recv()recvfrom()函數將永遠不會返回部分數據報。在內核完全接收並重組數據報之前,數據報不可用於應用程序。

有趣的是,這是沒有太大的(任意?)問題的今天,其他網絡編程接口不上行爲一致時,所提供的緩衝區太小的:

傳統的伯克利版本的套接字API截斷數據報,丟棄任何多餘的數據。應用程序是否被通知取決於版本。 (4。3BSD Reno及更高版本可以通知應用程序數據報已被截斷。)

SVR4(包括Solaris 2.x)下的套接字API不會截斷數據報。任何多餘的數據在後續讀取中返回。應用程序沒有通知從單個UDP數據報中實現了多個讀取。

TLI API不會丟棄數據。而是返回一個標誌,表示有更多數據可用,並且應用程序的後續讀取將返回數據報的其餘部分。

(史蒂文斯,TCP/IP詳解,第1卷,第160頁)

+0

它看起來像是可以在Linux中傳遞和接收MSG_TRUNC標誌到'recvmsg'。在手冊頁recv(2)中記錄。另一方面,也許我誤讀了,但是我只能找到'socket(2)'的manpage中記錄的丟棄行爲,它只爲'SOCK_SEQPACKET'套接字提及。我從來沒有親自使用過這些。 – 2010-02-11 09:10:58

+0

'MSG_TRUNC'作爲'recv(2)'的參數不是標準的。它在FreeBSD或Mac OS X上都不可用(我目前可以訪問的系統,其他人可能也適用)。 'MSG_TRUNC'可以在'struct msghdr'的'flags'成員的Linux,FreeBSD和Mac OS X上傳遞給'recvmsg(2)'。在任何情況下,即使使用Linux上的'recv(2)',如果傳遞的緩衝區不夠大,數據報將被截斷。如果在那裏使用MSG_TRUNC,調用者必須檢查返回值並將其與緩衝區的大小進行比較。它會知道數據丟失,但仍然丟失。 – 2010-02-11 16:07:16

+0

謝謝!這意味着UDP是**真的**數據包導向... – Uwe 2010-02-11 17:34:43

0

我相信你只能得到一個或零個數據報。但這一刻我不能支持這一點。也許別人可以提供一個很好的參考?

編輯:我敢肯定,你不能接收一半的數據報。數據報已經到達緩衝區,或者沒有。

+0

我相信這是正確的。如果它不適合您提供的緩衝區,或者如果您的mbufs不夠大(有時會發生大量碎片數據報),您也可能會遇到錯誤。 – 2010-02-10 22:03:38

+0

mbufs是一個BSD內核數據結構。他們沒有接觸用戶所在地。 – 2010-02-11 16:08:30

1

是的,UDP只是返回在那個數據報中傳輸的數據。 UDP不像TCP那樣面向流。數據報是離散傳輸,並不以任何方式與其他數據報綁定。這就是TCP的套接字選項爲SOCK_STREAM的原因。

這樣做的好處在於,您可以感受到單獨的傳輸,這對於TCP來說並不容易。

+0

感謝你們倆。 我知道面向流的TCP(SOCK_STREAM)和麪向數據包的UDP(SOCK_DGRAM)之間的區別。我只是不確定一個非阻塞的UDP recv()是否也是面向數據包的。引用recv()手冊頁: ...如果在套接字上沒有可用的消息,則接收調用將等待消息到達,除非套接字是非阻塞的(請參閱fcntl(2)),在這種情況下返回值-1,並將外部變量errno設置爲EAGAIN或EWOULDBLOCK。 **接收的電話通常會返回任何可用的數據,** ... – Uwe 2010-02-10 20:38:07