sendto ()возвращает значения, превышающие MTU на SOCK _DGRAM (UDP )сокет

В настоящее время я пишу клиент/сервер UDP (на GNU/Linux ). Я использую sendto()для отправки сообщений через сокет SOCK_DGRAM, который не привязан к порту.

На странице руководства send (2 )указано, что:

On success, these calls return the number of characters sent. On error, -1 is returned, and errno is set appropriately.

Однако sendto всегда возвращает параметр длины, указывающий на успех. С сообщениями больше 65507(0xFFE3)байт, он возвращает ошибку Message too long.

Для сообщений, превышающих MTU в 1500 байт, сервер всегда получает (через recvfrom()). сообщения размером ровно 1500 байт, просто вырезая сообщение без дополнительного уведомления.

(Почему )такое поведение предусмотрено, и есть ли способ получить уведомление о том, что что-то пошло не так?

Единственный обходной путь, который я могу сейчас придумать, — просто принять MTU равным 1500 байт и никогда не отправлять большие пакеты.

Это соответствующий метод:

int udp_send(uint32_t dst, uint16_t port, char *msg, unsigned len) {
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock < 0) {
            perror("Could not open socket");
            return -1;
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(dst);

    int count = sendto(sock, msg, len, 0,
            (struct sockaddr *) &addr, sizeof(addr));
    printf("bytes sent: %d\n", count);

    if(count < 0) {
            perror("Could not send message");
            return -3;
    }

    close(sock);
    return count;
}

Вызов, в котором происходит описанное нежелательное поведение, будет udp _отправить (0x7F000001, 1337, bigbuf,1501 ); который вернет 1501 при отправке только 1500 байт.

0
задан mic_e 29 May 2014 в 12:29
поделиться