2 回答

TA貢獻(xiàn)1934條經(jīng)驗 獲得超2個贊
1.一次recvfrom()調(diào)用只能返回一個UDP數(shù)據(jù)包。
2.send()函數(shù)參數(shù)中的buffer長度有限制,此長度限制取決于底層協(xié)議的數(shù)據(jù)包最大長度,這個長度可以通過getsockopt函數(shù)設(shè)置SO_MAX_MSG_SIZE參數(shù)獲得,如果發(fā)送的數(shù)據(jù)包超過底層協(xié)議的最大長度則返回WSAEMSGSIZE錯誤,同時不發(fā)送任何數(shù)據(jù)。
sendto()函數(shù)參數(shù)中的buffer長度也有限制,這個限制更明顯一些,數(shù)據(jù)包的數(shù)據(jù)部分(不包括數(shù)據(jù)頭)的長度不能超過512字節(jié)。
3.send()與sendto()正常返回均不能保證發(fā)送的數(shù)據(jù)被接受方正確接收,還要看緩沖區(qū)是否已滿。當(dāng)緩沖區(qū)為空時,recv與recvfrom均阻塞等待(除非設(shè)置為非阻塞,此時將返回WSAEWOULDBLOCK錯誤),因此只要socket正常連接,且緩沖區(qū)有數(shù)據(jù)內(nèi)容,recv與recvfrom函數(shù)雖延遲但均能正常接收數(shù)據(jù)包。
希望我的回答你能滿意:)
你好,我看了你添加的內(nèi)容,我上面所說的最大長度512字節(jié)是指UDP數(shù)據(jù)包可以發(fā)送的的最大長度,針對的是sendto函數(shù),而你測試時使用的則是TCP連接中的send函數(shù),兩者使用的協(xié)議不同,因此緩沖區(qū)的長度當(dāng)然不同了,我使用getsockopt測試,得到我本機(jī)接受方的最大緩沖為8192字節(jié),測試代碼如下:
#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;
}
在此補(bǔ)充一下,上面所說SO_MAX_MSG_SIZE只針對UDP這種數(shù)據(jù)報形式的協(xié)議有效,而對于基于流的TCP/IP無效,因此在此使用SO_RCVBUF參數(shù),如果還有問題敬請指出:)

TA貢獻(xiàn)1866條經(jīng)驗 獲得超5個贊
你看他的參數(shù)明顯一次只能返回一個啊
UDP發(fā)送的包尺寸超過網(wǎng)絡(luò)允許的大小,發(fā)送行為將會失敗。
即便對方馬上就接受也未必接受得到。UDP有一個緩沖區(qū),發(fā)過來的包會放在緩沖區(qū)里,recv是從這個緩沖區(qū)里面讀取。所以send之后一段時間再調(diào)用recv是可以接收到這個包的,前提是這個包成功被放入緩沖區(qū)了。但是如果send的時候緩沖區(qū)已經(jīng)滿了,或者發(fā)送時發(fā)生了錯誤,這樣不管你什么時候recv都得不到這個包。
添加回答
舉報