红联Linux门户
Linux帮助

求助:sendto()发送UDP数据包失败:message too long该如何解决?

发布时间:2012-03-24 23:17:25来源:红联作者:zhl2001xlh800
我想使用sendto()发送视频和音频UDP多播数据包,我使用getsockopt(context_data->socket,SOL_SOCKET, SO_SNDBUF, &bufsize, &size);获得发送缓冲区的大小为114688,但是实际上当我发送的数据包还不到这个值的时候(大约大于65536时就会失败),就会发送失败,返回值-1,消息为message too long.

在网上搜了一下说,出现这个错误时,应该手动设置发送缓冲区的大小为所发数据包的最大值,于是我就使用setsockopt()将发送缓冲区的大小设置为200000,这时我再使用getsockopt()获得发送缓冲区的大小为262142,并不是我所希望设置的值,并且这时发送大的数据包时仍然会出错。我所设置的发送缓冲区的大小并没有起到作用。

真的不知到这是为什么,求高手指点一下,这到底是怎么回事?

我使用的系统是ubuntu 11.04,我在ubuntu 11.10上的结果是一样的。

我用来设置socket的代码:

unsigned char *output_buffer = (unsigned char*)av_malloc(IO_BUFFER_SIZE);
if (NULL == output_buffer) {
printf("Couldn't allocate input buffer.\n");
return NULL;
}

output_context_data_t *context_data = (output_context_data_t *)malloc(sizeof(output_context_data_t));
if (NULL == context_data) {
printf("Could not allocate output context data.\n");
av_free(output_buffer);
return NULL;
}

context_data->socket = socket(AF_INET, SOCK_DGRAM, 0);
if(context_data->socket < 0) {
printf("socket creating fail!\n");
return NULL;
}

context_data->socket_addr->sin_family = AF_INET;
context_data->socket_addr->sin_port = htons(output_port);
ret = inet_pton(AF_INET, output_ip, &(context_data->socket_addr->sin_addr));
if(0 == ret) {
printf("inet_pton fail!\n");
return NULL;
}

ret = setsockopt(context_data->socket, IPPROTO_IP, IP_MULTICAST_TTL,
&option_ttl, sizeof(int));
if(ret < 0) {
printf("ttl configuration fail!\n");
return NULL;
}

ret = setsockopt(context_data->socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
if(ret < 0) {
printf("resue configuration fail!\n");
return NULL;
}

ret = setsockopt(context_data->socket, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp));
if(ret < 0) {
printf("sending buffer size configuration fail!\n");
return NULL;
}

发送UDP数据包的函数如下:

int send_size = sendto(context_data->socket, buf, buf_size, 0, (struct sockaddr *)context_data->socket_addr, sizeof(*(context_data->socket_addr)));
//这里我所要发送的数据在buf中,大小为buf_size。

以下为我获得发送缓冲区大小的代码:
int bufsize;
int size = sizeof(bufsize);
getsockopt(context_data->socket,SOL_SOCKET, SO_SNDBUF, &bufsize, &size);

以下为我设置发送缓冲区的代码:
tmp = 200000;
ret = setsockopt(context_data->socket, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp));
if(ret < 0) {
printf("sending buffer size configuration fail!\n");
return NULL;
}
文章评论

共有 1 条评论

  1. 于 2012-03-26 13:13:08发表:

    这是因为一个packet的最大长度不能超过65535
    udp的最大长度不能超过一个packet的长度