Гибкое применение розеток

Я пишу игру, в которую играю по локальной сети с сокетом. Я использую префикс длиной 4 байта, чтобы узнать, сколько данных в остальных, например:

void trust_recv(int sock, int length, char *buffer)
{
    int recved = 0;
    int justRecv;

    while(recved < length) {
        justRecv = recv(sock, buffer + recved, length - recved, 0);
        if (justRecv < 0) return;

        recved += justRecv;
    }
}

void onDataArrival(int sock)
{
    int length;
    char *data;

    trust_recv(sock, 4, (char *) &length);
    data = new char[length];

    trust_recv(sock, length, data);
    do_somethings_with_data(data);
}

Проблема в том, что если кто-то (например, злоумышленник или хакер) отправляет данные в другом формате (может быть, всего 2 байта или длина оставшейся части меньше значения префикса 4 байта) или возникает проблема с сетью, мое приложение перейдет в «не отвечает» "состояние и нужно закрыть (потому что я использую блокирующий сокет). Как сделать мое приложение сокета более гибким, но не переключать сокет в неблокирующий режим, чтобы решить эту проблему? (Или любые идеи для организации данных или алгоритмов)


person Bình Nguyên    schedule 21.01.2013    source источник
comment
sizeof(int) не может быть 4. Вы должны использовать int32_t и sizeof(length) для защиты от повреждения стека.   -  person James McLaughlin    schedule 21.01.2013
comment
@JamesMcLaughlin: Спасибо, я сообщу это   -  person Bình Nguyên    schedule 21.01.2013


Ответы (1)


Вы можете установить тайм-аут приема на этапе установки сокета с помощью setsockopt() вызова и SO_RCVTIMEO параметра;

struct timeval tv;

tv.tv_sec =8;
tv.tv_usec = 0 ;

if (setsockopt (your_sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) 
    perror(“setsockopt error”);

затем проверьте возвращение recv() и его errno

if (justRecv < 0)
{
    if (errno == EAGAIN)
        perror("TIMEOUT!");
    return;
}    
person Davide Berra    schedule 21.01.2013
comment
Спасибо за отличный ответ, кстати, есть ли другие способы решить эту проблему? - person Bình Nguyên; 21.01.2013