Клиент сообщил об ошибке, которую я не смог понять. Клиент, основанный на TCP, подключается к серверу, с которого он получает данные, редко отправляя что-либо. Обычно все работает отлично, но когда-то в голубой луны ситуация, как это происходит:Каким образом вызов чтения сокета tcp никогда не возвращается
- сервер отправляет некоторые данные
- клиент получает данные
- клиент обрабатывает данные
- ... и в сервер отправляет тем временем намного больше данных
- клиент заканчивает обработку
- клиент пытается прочитать данные из сокета
- клиент навсегда нависает на первом чтение() заявление после обработки
- сервер закрывает соединение
- клиент по-прежнему висит
Вот как установлено соединение TCP (лишен всех журналов, вернуть чеки и т.д.)
ret = inet_pton(AF_INET, conn->address, &addr.sin_addr);
addr.sin_port = htons(conn->port); /* Server port */
addr.sin_family = AF_INET;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(sock, (struct sockaddr *) &addr, sizeof(addr));
А вот чтение обертка:
int32_t _readn (int fd, uint8_t *vptr, int32_t n)
{
int32_t nleft;
int32_t nread;
uint8_t* ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nread = read (fd, ptr, nleft)) < 0) {
if (errno == EINTR) {
nread = 0;
} else {
return E_NETWORK_ERROR;
}
} else if (nread == 0) {
break;
}
nleft -= nread;
ptr += nread;
}
return (n-nleft);
}
возможно ли вызов чтения для блокировки навсегда, даже после закрытия соединения?
Есть ли какая-то сложная ошибка в моей обертке, которую я не заметил, что может вызвать это? Должен ли я устанавливать флажки для сокета при подключении?
Есть ли причина, почему не использовать его без блокировки и положить как 'select' на fd вместо этого? – Jite
Нет, их нет. Это может быть решением. Есть несколько других способов, я могу думать, что это было бы хорошим способом. Но я хочу знать источник проблемы. – Dariusz