亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

您好,關于recvfrom()的一次調用只能返回一個UDP包。這種說法正確嗎?

您好,關于recvfrom()的一次調用只能返回一個UDP包。這種說法正確嗎?

桃花長相依 2021-11-04 11:07:58
1.recvfrom()的一次調用只能返回一個UDP包。此種說法正確嗎?2.send()和sendto()函數參數中的buffer有長度限制嗎?我對左稚幻回答的第二條有疑問:我一個程序中,接收端一下發了1024*1024字節(一次send調用,設置buffer為1024*1024長,全填滿了數據),接收端也用一次recv調用(提供了1024*1024長的緩沖區),能一次完全接收到發送的1024*1024個字節。為什么?(我是在本機上測試的)
查看完整描述

2 回答

?
撒科打諢

TA貢獻1934條經驗 獲得超2個贊

1.一次recvfrom()調用只能返回一個UDP數據包。
2.send()函數參數中的buffer長度有限制,此長度限制取決于底層協議的數據包最大長度,這個長度可以通過getsockopt函數設置SO_MAX_MSG_SIZE參數獲得,如果發送的數據包超過底層協議的最大長度則返回WSAEMSGSIZE錯誤,同時不發送任何數據。
sendto()函數參數中的buffer長度也有限制,這個限制更明顯一些,數據包的數據部分(不包括數據頭)的長度不能超過512字節。
3.send()與sendto()正常返回均不能保證發送的數據被接受方正確接收,還要看緩沖區是否已滿。當緩沖區為空時,recv與recvfrom均阻塞等待(除非設置為非阻塞,此時將返回WSAEWOULDBLOCK錯誤),因此只要socket正常連接,且緩沖區有數據內容,recv與recvfrom函數雖延遲但均能正常接收數據包。
希望我的回答你能滿意:)

你好,我看了你添加的內容,我上面所說的最大長度512字節是指UDP數據包可以發送的的最大長度,針對的是sendto函數,而你測試時使用的則是TCP連接中的send函數,兩者使用的協議不同,因此緩沖區的長度當然不同了,我使用getsockopt測試,得到我本機接受方的最大緩沖為8192字節,測試代碼如下:
#include <stdio.h>
#include "winsock2.h"

void main() {

WSADATA wsaData;
SOCKET ListenSocket;
sockaddr_in service;

int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if( iResult != NO_ERROR )
printf("Error at WSAStartup\n");

ListenSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (ListenSocket == INVALID_SOCKET) {
printf("Error at socket()\n");
WSACleanup();
return;
}

hostent* thisHost;
char* ip;
u_short port;
port = 27015;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);

service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);

if ( bind( ListenSocket,(SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
printf("bind failed\n");
closesocket(ListenSocket);
return;
}

int optVal;
int optLen = sizeof(int);

getsockopt(ListenSocket, SOL_SOCKET, SO_RCVBUF, (char*)&optVal, &optLen);
printf("The max length is %d\n", optVal);
WSACleanup();
return;
}

在此補充一下,上面所說SO_MAX_MSG_SIZE只針對UDP這種數據報形式的協議有效,而對于基于流的TCP/IP無效,因此在此使用SO_RCVBUF參數,如果還有問題敬請指出:)



查看完整回答
反對 回復 2021-11-09
?
心有法竹

TA貢獻1866條經驗 獲得超5個贊

你看他的參數明顯一次只能返回一個啊
UDP發送的包尺寸超過網絡允許的大小,發送行為將會失敗。
即便對方馬上就接受也未必接受得到。UDP有一個緩沖區,發過來的包會放在緩沖區里,recv是從這個緩沖區里面讀取。所以send之后一段時間再調用recv是可以接收到這個包的,前提是這個包成功被放入緩沖區了。但是如果send的時候緩沖區已經滿了,或者發送時發生了錯誤,這樣不管你什么時候recv都得不到這個包。

查看完整回答
反對 回復 2021-11-09
  • 2 回答
  • 0 關注
  • 778 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號