Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 506 Vote(s) - 3.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to solve: sending UDP packet using Sendto() got "message too long"

#1
I want to use the sendto() API to send video and audio data through UDP packet. The sending buffer size I got using getsockopt() is 114688, however, sendto() returned -1 when the data packet less than 65536 not 114688. And the error message is Message too long.

When I used setsockopt() to adjust the sending buffer size as 200000, I used getsockopt() and found the sending buffer size was not 200000 but 262142. So I still got the same error when I sent data packet with a size bigger than 65536.

I am confused about this situation. I want to know what the reason is and how to solve this problem.

When I used FFMPEG library to send the video and audio packet, there is no error. So I am sure there is a solution for this problem and I missed something.

Is there anyone can help me about this problem? I really can not understand what the reason is.

The OS I used is ubuntu 11.04,I got the same results in ubuntu 11.10.

That is the code I used to create socket and configure the parameter:

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


That is the code to send UDP packet:

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.

That is the code I used to get the sending buffer size:

int bufsize;
int size = sizeof(bufsize);
getsockopt(context_data->socket,SOL_SOCKET, SO_SNDBUF, &bufsize, &size);

That is the code I used to configure the sending buffer 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;
}
Reply

#2
You can not send messages (datagrams) larger than 2^16 65536 octets with UDP. The length field of a UDP packet is 16 bits. The buffer sizes you're requesting are not about the size for a packet, but how many octets the OS does buffer incoming and outgoing in total (spread over multiple packets). But a single packet can not get larger.
Reply

#3
Per @datenwolf's answer, you simply can't send more than 64k in a single UDP datagram, as that limit is implicit in the two-byte length field in the protocol.

Furthermore, it's not actually a good idea to send even that much at once. You should limit your packets to the MTU on the path between the two ends (typically in the region of 1500 bytes or less) so that you don't get _fragmentation_ in the IP layer.

Fragmentation is bad - ok?
Reply

#4
Why not just call `sendto` several times, with an offset into the buffer?

int sendto_bigbuffer(int sock, const void *buffer, const size_t buflen, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen)
{
size_t sendlen = MIN(buflen, 1024);
size_t remlen = buflen;
const void *curpos = buffer;

while (remlen > 0)
{
ssize_t len = sendto(sock, curpos, sendlen, flags, dest_addr, addrlen);
if (len == -1)
return -1;

curpos += len;
remlen -= len;
sendlen = MIN(remlen, 1024);
}

return buflen;
}

Something like the above function will send the buffer 1024 bytes at a time.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through