您好,关于recvfrom()的一次调用只能返回一个UDP包。这种说法正确吗?

1.recvfrom()的一次调用只能返回一个UDP包。此种说法正确吗?
2.send()和sendto()函数参数中的buffer有长度限制吗?
我对左稚幻回答的第二条有疑问:
我一个程序中,接收端一下发了1024*1024字节(一次send调用,设置buffer为1024*1024长,全填满了数据),接收端也用一次recv调用(提供了1024*1024长的缓冲区),能一次完全接收到发送的1024*1024个字节。为什么?
(我是在本机上测试的)

桃花长相依
浏览 495回答 2
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参数,如果还有问题敬请指出:)

心有法竹

你看他的参数明显一次只能返回一个啊UDP发送的包尺寸超过网络允许的大小,发送行为将会失败。即便对方马上就接受也未必接受得到。UDP有一个缓冲区,发过来的包会放在缓冲区里,recv是从这个缓冲区里面读取。所以send之后一段时间再调用recv是可以接收到这个包的,前提是这个包成功被放入缓冲区了。但是如果send的时候缓冲区已经满了,或者发送时发生了错误,这样不管你什么时候recv都得不到这个包。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java
JQuery