當前位置:編程學習大全網 - 編程語言 - 使用recvfrom接收UDP包在Windows和Linux平臺的不同表現

使用recvfrom接收UDP包在Windows和Linux平臺的不同表現

操作系統的UDP接收流程如下:收到壹個UDP包後,驗證沒有錯誤後,放入壹個包隊列中,隊列中的每壹個元素就是壹個完整的UDP包。當應用程序通過recvfrom()讀取時,OS把相應的壹個完整UDP包取出,然後拷貝到用戶提供的內存中,物理用戶提供的內存大小是多少,OS都會完整取出壹個UDP包。如果用戶提供的內存小於這個UDP包的大小,那麽在填充慢內存後,UDP包剩余的部分就會被丟棄,以後再也無法取回。

這與TCP接收完全不同,TCP沒有完整包的概念,也沒有邊界,OS只會取出用戶要求的大小,剩余的仍然保留在OS中,下次還可以繼續取出。

socket編程雖然是事實上的標準,而且不同平臺提供的接口函數也非常類似,但畢竟它不存在嚴格的標準。所以各個平臺的實現也不完全兼容。下面就從recvfrom()這個函數看看Window平臺和Linux平臺的不同。

Windows平臺的表現

int

WSAAPI

recvfrom(

_In_ SOCKET s,

_Out_writes_bytes_to_(len, return) __out_data_source(NETWORK) char FAR * buf,

_In_ int len,

_In_ int flags,

_Out_writes_bytes_to_opt_(*fromlen, *fromlen) struct sockaddr FAR * from,

_Inout_opt_ int FAR * fromlen

);

再看MSDN說明:

If the datagram or message is larger than the buffer specified, the buffer is filled with the first part of the datagram, and recvfrom generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost.

可以看出,buf大小小於UDP包大小的時候,recvfrom()會返回-1,並設置錯誤WSAEMSGSIZE。

實際編程測試驗證確實是這樣的表現。

Linux平臺的表現

__extern_always_inline ssize_t

recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags,

__SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len)

可以看出與Windows平臺的函數原型相同。但是在其man手冊裏,沒有看到UDP包大於接收緩沖區情況的特殊說明。

寫代碼測試表明,buf小於UDP包大小的時候,recvfrom()仍然返回復制到緩沖區的字節數,調用者無法得知UDP包被截斷的情況。

  • 上一篇:讓孩子從小學習編程,真的能提高孩子的核心競爭力嗎?
  • 下一篇:如何填寫簡歷
  • copyright 2024編程學習大全網