android - 在 Android native 代码中挂起 TCP 套接字发送调用

标签 android c sockets tcp

我在 Android 上使用套接字发送(或写入)功能时遇到问题。

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

套接字在另一个线程(我使用pthread)上使用,其中调用了recv。但是,我这次没有向Android发送数据,所以当我调用send时recv只是在等待。 我确信另一端正在等待数据——我看到另一端的recv每3秒返回一次EAGAIN(我设置了超时)并立即再次调用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();

最佳答案

在 Nikolai N Fetissov 的评论帮助下问题得到了解决 - 他正确的问题解开了我的思路,我在 RWMutex 中发现了一个问题。

关于android - 在 Android native 代码中挂起 TCP 套接字发送调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7987163/

相关文章:

android - setprop libc.debug.malloc = 1 不工作

android - Android native 服务器列表

c - 如何将计算有界切片数量的时间复杂度降低到 O(N)?

c - 释放c中的链表

c - 为什么客户端将网络服务器的消息回显给它?

python - urllib.error.URLError : <urlopen error [Errno 11002] getaddrinfo failed>?

c++ - TCP WSASend 完成标准

java - 从对话框 fragment 返回后,工具栏 View 引用变为空

android - 如何获取与SD卡上的音频添加的日期?

c - strcat with char 来自 c 中的数组