在Android本机代码中挂起TCP套接字发送调用

时间:2011-11-02 20:52:42

标签: android c sockets tcp

我在android上遇到套接字发送(或写入)功能的问题。

我在Linux和Android上使用了我的网络库。代码用C写成 在Android上,应用程序创建一个服务,该服务加载本机代码并在我的网络库的帮助下创建连接。连接是TCP套接字。当我调用send(或写入,没有区别)时,代码在大多数情况下挂起。有时,它会在10-120秒后展开。有时,它会等待更长时间(直到我杀死应用程序)。发送的数据大小约为40-50个字节。第一次数据发送(握手,5个字节)永远不会挂起(或者我很幸运)。挂起发送通常是握手数据包之后的下一步。第一次握手包发送和挂起发送之间的时间约为10-20秒。

套接字用于另一个线程(我使用pthread),其中调用recv。但是,我这次没有向Android发送数据,所以当我调用send时,recv正在等待。 我确信另一方正在等待数据 - 我看到另一方的recv每3秒返回一次EAGAIN(我设置超时)并立即再次调用recv。 Recv总是等待10个字节(最小包的大小)。

我无法在Linux-to-Android传输或Linux-to-Linux上重现此行为,仅在Adnroid-to-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 个答案:

答案 0 :(得分:1)

这个问题在Nikolai N Fetissov的评论中得到了解决 - 他的正确问题解除了我的思绪,我在RWMutex中发现了一个问题。