2015-05-09 5 views
0

Я делаю многопоточный TCP-сервер, когда я использую recv() в потоках, они не обновляют/не запускают/не запускают бесконечно (циклически), если recv() фактически получает некоторые данные.Тема не обновляется, но блокируется на recv()

Вот фрагмент кода изнутри цикла.

if(seconds < 15){ 
    printf("%f seconds passed: \r", seconds); 

    if ((read_size = recv(sock , client_message , 512 , 0)) > 0) 
    { 
     //Send the message back to client 
     reply_message = client_message; 
     (void)write(sock, reply_message, strlen(reply_message)); 
    } 

}else{ 
    // ... blah blah blah 
} 

Если я закомментировать внутренний IF заявление, нить работает & выходы Е() так быстро, как это возможно. Когда включен оператор IF, поток ожидает recv() и не обновляется (printf() не печатается), пока recv() не получил данные:/

Любые идеи?

+6

Ну вот что он должен делать. Что вы ожидали от этого? – univerio

+0

Он должен непрерывно распечатывать секунды, прошедшие до 15 секунд, одновременно получая данные. Однако, когда recv() используется, это не так, и другие условные операторы, основанные на переменной секунд, не выполняются из-за того, что recv() останавливает поток. – MissionGuy07

+2

Вы хотите совместить 'select' с 1-секундным таймаутом с' recv'. Также вы хотите, чтобы сокет не блокировался. Также вам нужно обрабатывать короткие чтения ... – Nemo

ответ

1

От RECV (2) - Linux страницы человека (см here):

Если сообщений нет на патроне, прием звонков ждать сообщений для прибыть, если сокет не блокирующим (см. fcntl (2)), , в этом случае возвращается значение -1, а внешняя переменная errno установлена ​​в EAGAIN или EWOULDBLOCK. Приобретенные звонки обычно возвращают любые доступные данные, вплоть до запрашиваемой суммы, а не ждать получения всей запрашиваемой суммы.

Так вот как работает recv. Если вы хотите, чтобы он немедленно возвращался, вы должны использовать неблокирующий режим (см. fcntl и select описаний).

// sock is the socket you want to make non-blocking 
int status = fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK); 

// handle the error 
if(status == -1) { 
    ... 
} 

Если вы хотите проверить, если есть что-нибудь, чтобы читать в гнездо

int count = 0; 
ioctl(sock, FIONREAD, &count); 

count это количество байт доступно в гнезде

 Смежные вопросы

  • Нет связанных вопросов^_^