Зависание на сокете TCP, отправка вызова в Android-коде - PullRequest
0 голосов
/ 03 ноября 2011

У меня проблема с функцией отправки (или записи) сокета на Android.

Есть моя сетевая библиотека, которую я использую на Linux и Android. Код написан на C.
На Android приложение создает сервис, который загружает собственный код и создает соединение с помощью моей сетевой библиотеки. Соединение - это сокет TCP. Когда я вызываю send (или пишу, без разницы), код в этом звонке зависает в большинстве случаев. Иногда он разворачивается через 10-120 секунд. Иногда он дольше ждет (пока я не убью приложение). Размер отправляемых данных составляет около 40-50 байт. Первая отправка данных (рукопожатие, 5 байт) никогда не зависает (или мне просто везет). Передача с зависанием, как правило, следующая после пакета рукопожатия. Время между отправкой первого рукопожатия и зависанием составляет около 10-20 секунд.

Сокет используется в другом потоке (я использую pthread), где вызывается recv. Но сейчас я не отправляю данные на Android, поэтому recv просто ждет, когда я позвоню send. Я уверен, что другая сторона ждет данных - я вижу, что recv на другой стороне возвращается с EAGAIN каждые 3 секунды (я установил тайм-аут) и сразу же вызывает recv снова. Recv всегда ожидает 10 байтов (минимальный размер пакета).

Я не могу воспроизвести это поведение при передаче с Linux на Android или с Linux на Linux, только на Adnroid-в-Linux. Я могу воспроизвести это на двух доступных мне разных устройствах Android, поэтому я не думаю, что это проблема сломанного оборудования одного конкретного устройства.

Я попытался установить параметры SO_KEEPALIVE и TCP_NODELAY безуспешно.

Что может вызывать зависание при отправке / записи вызовов и как я могу решить эту проблему?

Сокет, созданный с этим кодом:

int sockfd, n;
addrinfo hints, *res, *ressave;

bzero(&hints, sizeof(addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;

if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)
{ /* stripped error handling*/ }

ressave = res;

do
{
  sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  if (sockfd < 0) continue;
  if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
  {
     break; /* success */
  }

  close(sockfd); /* ignore this one */
} while ((res = res->ai_next) != NULL);

Зависание отправки:

mWriteMutex.lock();
mSocketMutex.lockRead();
ssize_t n = send(mSocket, pArray, size, 0);
mSocketMutex.unlock();
mWriteMutex.unlock();

1 Ответ

1 голос
/ 03 ноября 2011

Проблема решена с помощью Николая Н. Фетисова в комментариях - его правильный вопрос разблокировал мой разум, и я нашел проблему в RWMutex.

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