Как остановить операцию чтения на сокете? - PullRequest
2 голосов
/ 20 февраля 2009

Из одного потока я получил следующий код:

int next_stuff(char **code){
    ...       
    len=read(file_desc,buffer+end_len,packet_size-end_len);
    if(len<=0)
    {
        if(len==-1 && errno==EAGAIN) return(0);
        else return(-1);
    }
    ...
}

while (next_stuff(&buff) == 0)
{
    ...
}

В другом потоке я хотел бы закончить этот сокет и выйти из этой операции, но только делая

close(file_desc);

не заставляет чтение возвращаться неблокированным. Я что-то упустил?

EDIT:

выключение не работает также. И я пытаюсь это на Linux 2.6.23

Ответы [ 5 ]

2 голосов
/ 20 февраля 2009

выключение (fd, SHUT_RD);

$ man -s 2 shutdown

NAME shutdown - отключить часть полнодуплексного соединения

СИНТАКСИС

 #include <sys/socket.h>

 int     shutdown(int socket, int how);

ОПИСАНИЕ

 The shutdown() call causes all or part of a full-duplex connection on the socket 
 associated with socket to be shut down.  
 If how is SHUT_RD, further receives will be disallowed.  If how is 
 SHUT_WR, further sends will be
 disallowed.  If how is SHUT_RDWR, further sends and receives will be disallowed.

ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ

 The shutdown() function returns the value 0 if successful; otherwise the value -1 is 
 returned and the global variable errno is set to indicate the error.
1 голос
/ 20 февраля 2009

В общем, если вы не хотите блокировать вызовы сокетов, вы должны использовать select (), чтобы увидеть, готов ли сокет к чтению, записи или находится в состоянии ошибки. Кроме того, передайте значение времени ожидания для select (), чтобы этот вызов не блокировался вечно. После того, как вызов select () вернется, вы сможете увидеть, хочет ли приложение выйти, и если да, то сделать «правильную» вещь (решать вам).

0 голосов
/ 21 февраля 2009

Не думаю, что вы предоставили достаточно информации, чтобы ответить на этот вопрос. Например, если вы открыли сокет UDP, то закрытие на отправляющей стороне не окажет влияния на принимающую сторону. Если это TCP, то что-то еще не работает. Я полагаю, что если вы действительно имеете дело с сокетами, вы используете recv или recvfrom вместо read.

В случае TCP ваше чтение вернет 0 байтов, что указывает на то, что другая сторона закрыла соединение.

Если вы действительно делаете это между двумя потоками, а не двумя процессами, канал может быть более подходящим. Это не означает, что канал не может быть использован между двумя отдельными процессами, просто в этом случае требуется немного больше настройки.

0 голосов
/ 20 февраля 2009

Другие ответы о неблокирующих сокетах хороши, и я рекомендую перекодировать, чтобы использовать этот подход.

Однако, как прямой ответ на ваш вопрос, попробуйте вызвать shutdown () и посмотреть, не нарушит ли это другой поток. Боюсь, что close () просто уменьшает счетчик использования, а shutdown () будет активно разрушать сокет.

0 голосов
/ 20 февраля 2009

Если ваш вызов read () неблокирующий, он должен возвращаться довольно быстро, так как все, что он будет делать, это вставлять память. Чтобы предотвратить нанесение какого-либо ущерба, вы должны использовать мьютекс вокруг вашего вызова read () и close (), чтобы они не могли работать одновременно.

Если ваш сокет блокируется, я думаю, вы должны сделать его неблокирующим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...