我想使用sendto()API通过UDP数据包发送视频和音频数据。我使用getsockopt()获得的发送缓冲区大小为114688,但是,当数据包小于65536而不是114688时,sendto()返回-1。错误消息是Message too long。

当我使用setsockopt()将发送缓冲区的大小调整为200000时,我使用getsockopt()并发现发送缓冲区的大小不是200000,而是262142。因此,当我发送大小大于65536的数据包时,我仍然遇到相同的错误。 。

我对这种情况感到困惑。我想知道原因是什么以及如何解决这个问题。

当我使用FFMPEG库发送视频和音频数据包时,没有错误。因此,我确定有解决此问题的方法,并且我错过了一些事情。

有没有人可以帮助我解决这个问题?我真的不明白是什么原因。

我使用的操作系统是ubuntu 11.04,在ubuntu 11.10中也得到了相同的结果。

那就是我用来创建套接字和配置参数的代码:

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;
}

那就是发送UDP数据包的代码:
int send_size = sendto(context_data->socket, buf, buf_size, 0,
                      (struct sockaddr *)context_data->socket_addr, sizeof(*context_data->socket_addr)));
//the video or audio data is in buf and its size is 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;
}

最佳答案

您不能使用UDP发送大于2 ^ 16 65536个八位位组的消息(数据报)。 UDP数据包的长度字段为16位。您所请求的缓冲区大小与数据包的大小无关,而是操作系统总共缓冲传入和传出的字节数(分布在多个数据包中)。但是单个数据包不能变大。

关于c - 如何解决: sending UDP packet using Sendto() got “message too long” ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9853099/

10-15 01:22