2013-10-24 2 views
0

Я возился с C сокетами, пытаясь достичь определенной функциональности для своего приложения.Неблокируемое чтение, которое обновляет текущую позицию очереди данных

A, я могу создать сетевые сокеты, которые блокируются, когда я их прочитаю, а также обновить позицию file. Итак, если я прочитаю один пакет, следующий ожидающий вызов будет ждать, а затем даст мне следующий пакет.

B, я также могу создать сетевые сокеты, которые не блокируются (либо O_DONTBLOCK, либо с помощью recv() с флагом DONTWAIT). Однако после прочтения пакета и сокета, не получающего никаких новых данных, эти сокеты всегда, кажется, не блокируют (ура!) И сразу же возвращают данные с начала сокета.

Так функциональность выглядит немного как:
A:

return packet 1 
...wait... 
return packet 2 

B:

return packet 1 
return packet 1 
return packet 1 
return packet 1 
return packet 2 (which just arrived) 

Я пытаюсь выяснить, как считывать данные из сетевого сокета, так что оба не блокируют и не пытаются вернуть старые данные, когда ничего нового не прибыло. Как она стоит

recv(connfd, &packet, sizeof(packet_t), MSG_DONTWAIT); 

никогда не возвращает -1, что в документации по крайней мере, не должны указывать никаких новых данных.

Заранее благодарим за любой совет!

EDIT:

Я говорю о TCP сокетов. В частности, розетки, созданные с автодозвона что-то вроде

listenfd = socket(AF_INET, SOCK_STREAM, 0); 

это сопровождается тем, что я считаю, это стандартный код:

bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));  
listen(listenfd, 1); 
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 

затем код для чтения из этого нового сокета:

while (1){ 
    int n = recv(connfd, &packet, sizeof(packet_t), MSG_DONTWAIT); 
    if (n > 0) { 
     ...examine packet... 
    } 
} 

С установленным O_NONBLOCK или предоставлением флага MSG_DONTWAIT в recv, чтение не блокируется. Это здорово. Однако, что происходит, это то, что он постоянно читает (или «получает», я думаю) предыдущие данные до тех пор, пока не появятся новые данные, которые затем начнут возвращаться снова и снова. Поведение, которое я искал, из документации, которое это обеспечило бы, было бы для вызовов recv, сделанных после того, как данные были проверены, но пока новые данные еще не доступны, чтобы вернуть значение n < = 0.

+2

С какими гнездами вы говорите? Также предоставление SSCCE (http://sscce.org/), вероятно, хорошая идея. – alk

ответ

1

он постоянно читает (или «получает», я думаю) предыдущие данные, пока не появятся новые данные, которые затем будут возвращаться снова и снова.

Нет, это не так. Он либо возвращает следующий байт (ы) в потоке с положительным счетом, либо 0 указывает конец потока, либо -1 с errno, установленным на EAGAIN/EWOULDBLOCK.

У Ergo у вас должна быть ошибка в коде.

+0

Yup. Спасибо за подтверждение, выкопали немного и нашли его. – Phil

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