我想使用sendto()API通過UDP數據包發送視頻和音頻數據。我使用getsockopt()的發送緩衝區大小爲114688,但是,當數據包小於65536而不是114688時sendto()返回-1。並且錯誤消息是消息太長。當我使用setsockopt()調整發送緩衝區大小爲200000時,我使用getsockopt(),發現發送緩衝區大小不是200000,而是262142.因此,當我發送數據包的時候,仍然發生了同樣的錯誤尺寸大於65536.如何解決:使用Sendto發送UDP數據包()得到「消息太長」
我對這種情況感到困惑。我想知道原因是什麼以及如何解決這個問題。
當我用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;
}
SO有什麼辦法可以改變傳出的緩衝區大小嗎? – user1290120 2012-03-24 21:39:13
@ user1290120:您可以更改將保存多個獨立傳出數據報的緩衝區的大小。但是沒有一個數據報可以大於65536個八位字節(字節),這是UDP協議本身的一個限制,而且沒有辦法解決這個問題。但是大數據報可能會丟棄。一個數據包不能大於整個路由上的最小MTU。如果你在以太網鏈路上,這個MTU不可避免地<9000,更可能<1500,對於你典型的DSL撥號,它<1490。 – datenwolf 2012-03-24 22:18:23
@ user1290120:所以你可以改變的是,多少個單獨的數據報可以被「保留」,但不是單個數據報的最大大小。 – datenwolf 2012-03-24 22:19:11