recvfrom()的一次调用只能返回一个UDP包。此种说法正确吗?
1.recvfrom()的一次调用只能返回一个UDP包。此种说法正确吗?2.send()和sendto()函数参数中的buffer有长度限制吗?我对左稚幻回答的第二条有疑...
1.recvfrom()的一次调用只能返回一个UDP包。此种说法正确吗?
2.send()和sendto()函数参数中的buffer有长度限制吗?
我对左稚幻回答的第二条有疑问:
我一个程序中,接收端一下发了1024*1024字节(一次send调用,设置buffer为1024*1024长,全填满了数据),接收端也用一次recv调用(提供了1024*1024长的缓冲区),能一次完全接收到发送的1024*1024个字节。为什么?
(我是在本机上测试的) 展开
2.send()和sendto()函数参数中的buffer有长度限制吗?
我对左稚幻回答的第二条有疑问:
我一个程序中,接收端一下发了1024*1024字节(一次send调用,设置buffer为1024*1024长,全填满了数据),接收端也用一次recv调用(提供了1024*1024长的缓冲区),能一次完全接收到发送的1024*1024个字节。为什么?
(我是在本机上测试的) 展开
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参数,如果还有问题敬请指出:)
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都得不到这个包。
UDP发送的包尺寸超过网络允许的大小,发送行为将会失败。
即便对方马上就接受也未必接受得到。UDP有一个缓冲区,发过来的包会放在缓冲区里,recv是从这个缓冲区里面读取。所以send之后一段时间再调用recv是可以接收到这个包的,前提是这个包成功被放入缓冲区了。但是如果send的时候缓冲区已经满了,或者发送时发生了错误,这样不管你什么时候recv都得不到这个包。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询