【发布时间】:2019-10-25 11:51:22
【问题描述】:
以下代码来自 Git。它加入一个多播组并接收数据包。
这里我们循环并在一个名为msgbuf的缓冲区中接收数据:
while (1)
{
char msgbuf[MSGBUFSIZE];
const int addrlen = sizeof(addr);
const int nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *) &addr, &addrlen);
我如何选择缓冲区msgBuf 的大小? 是否必须是最大数据包大小?还是在处理第一个数据包时需要存储多个数据包?
完整代码:
int main(int argc, char *argv[])
{
if (argc != 3) {
printf("Command line args should be multicast group and port\n");
printf("(e.g. for SSDP, `listener 239.255.255.250 1900`)\n");
return 1;
}
char* group = argv[1]; // e.g. 239.255.255.250 for SSDP
int port = atoi(argv[2]); // 0 if error, which is an invalid port
if(port <= 0)
{
perror("Invalid port");
return 1;
}
// create what looks like an ordinary UDP socket
//
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
perror("socket");
return 1;
}
// allow multiple sockets to use the same PORT number
//
u_int yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &yes, sizeof(yes)) < 0)
{
perror("Reusing ADDR failed");
return 1;
}
// set up destination address
//
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY); // differs from sender
addr.sin_port = htons(port);
// bind to receive address
//
if (bind(fd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
{
perror("bind");
return 1;
}
// use setsockopt() to request that the kernel join a multicast group
//
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mreq, sizeof(mreq)) < 0)
{
perror("setsockopt");
return 1;
}
// now just enter a read-print loop
//
while (1)
{
char msgbuf[MSGBUFSIZE];
const int addrlen = sizeof(addr);
const int nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *) &addr, &addrlen);
if (nbytes < 0)
{
perror("recvfrom");
return 1;
}
msgbuf[nbytes] = '\0';
puts(msgbuf);
}
return 0;
}
【问题讨论】:
-
如果
recvfrom()读取MSGBUFSIZE字节,代码会导致UB。然后msgbuf[nbytes] = '\0':导致缓冲区溢出。如果那是生产代码,那么实际上包似乎更小 -
@IngoLeonhardt 我很欣赏你的观点,但问题是关于如何调整缓冲区的大小,所以说有溢出有点毫无意义。通常,我需要知道如何确定缓冲区大小。它是基于最大的数据包大小吗?或者,我是否必须存储多个数据包,从而使缓冲区变大?
-
我知道这有点过时了。你的问题的答案当然取决于具体的沟通,我不知道。但至少缓冲区溢出可能表明应该不需要在该通信中存储多个数据包,因为我认为在这种情况下会发生溢出
-
@IngoLeonhardt 不用担心,我并不是要听起来粗鲁,我只是想重定向到它需要存储一个数据包还是多个数据包的问题。我认为它只是一个数据包(操作系统缓冲区可能存储任何累积?)
-
我从来没有觉得你很粗鲁 :-) 如果我最后的评论给你的印象是因为我不是母语人士。希望您的问题能引起了解更多的人的兴趣
标签: c sockets udp multicast berkeley-sockets