Android 套接字每 20 秒卡住一次

标签 android c sockets tcp

我在 Action 游戏中使用 TCP 套接字连接,我们使用锁步同步,客户端每秒将接收 20 - 40 个数据包。游戏在PC上运行时可以正常运行,但在Android设备上运行时, socket 每隔20秒就会卡住

Server sends 5 packets per second

我曾尝试使用 Unity3D 的 C# 套接字、Android Java 套接字和 Android native C 套接字以及阻塞/非阻塞模式,每个数据包的小/大(1 字节/100 字节)数据,每个数据包更少/更多(5/50)第二,使用单线程/主线程,在多个Android设备上,它们都有同样的问题。

PS:20 秒的持续时间似乎是基于设备,而不是我的应用程序或连接;这意味着如果上一次卡住发生在 1:00:00,下一次卡住将发生在 1:00:20,即使我们重新连接或重新启动应用程序也是如此。

Android 原生 C 代码:

    extern "C" JNIEXPORT int JNICALL
Java_com_example_ymoon_sockettest_MainActivity_connect(JNIEnv *env, jobject /* this */)
{
    __android_log_print(ANDROID_LOG_INFO, "CSocket", "Connecting...");

    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) return -1;

    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));

    server.sin_family = AF_INET;
    server.sin_port   = htons(12350);
    server.sin_addr.s_addr = inet_addr("192.168.3.66");

    if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0)
    {
        close(sock);
        return -2;
    }

    __android_log_print(ANDROID_LOG_INFO, "CSocket", "Connected");

    char buf[100];

    int t = -1;
    int received = 0;
    while (true)
    {
        int count = recv(sock, &buf, 100, 0);
        if (count < 1) break;

        received += count;

        struct timeval tv;
        gettimeofday(&tv, NULL);

        int m = tv.tv_sec * 1000 + tv.tv_usec / 1000;
        int diff = m - t;
        t = m;
        std::string p = t < 0 ? "" : diff < 50 ? "-" : diff < 100 ? "-|" : diff < 150 ? "--|" :
            diff < 250 ? "---|" :  diff < 500 ? "----|" : diff < 1000 ? "-----|" : "------|";
        __android_log_print(diff > 500 ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO,
                            "CSocket", "%i | %s %i", received, p.c_str(), diff);
    }

    close(sock);

    return 0;
}

我做错了什么吗? 这是我第一次在 stackoverflow 上提问,抱歉我的英语不好,感谢任何帮助或建议,谢谢。

编辑:添加服务器代码,我重写了一个简单的tcp服务器来测试(Window平台)

 int main()
{

    addrinfo conf, *add = nullptr;
    memset(&conf, 0, sizeof(conf));

    conf.ai_flags    = AI_PASSIVE;
    conf.ai_socktype = SOCK_STREAM;
    conf.ai_family   = AF_INET;

    if (getaddrinfo(nullptr, "12350", &conf, &add)) return 0;

    SOCKET serverSock = socket(AF_INET, SOCK_STREAM, 0);

    char opt = 1;
    if (setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
        setsockopt(serverSock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) == -1 ||
        bind(serverSock, add->ai_addr, add->ai_addrlen) == -1 ||
        listen(serverSock, 0) == -1)
    {
        close(serverSock);
        return 0;
    }

    printf("Listening....\n");

    sockaddr_storage incoming_addr;

    int size = sizeof(incoming_addr);
    SOCKET clientSock = accept(serverSock, (sockaddr*)&incoming_addr, &size);

    printf("Client connected\n");

    char buf[1] = { 0 };
    int sendCount = 0;
    while (true)
    {
        time_t t = time(nullptr);
        tm *lt = localtime(&t);
        printf("%02d:%02d:%02d Send to client %i\n", lt->tm_hour, lt->tm_min, lt->tm_sec, ++sendCount);

        if (send(clientSock, buf, 1, 0) < 1) break;
        Sleep(200);
    }

    close(serverSock);

    return 0;
}

编辑:添加 WireShark 捕获图像: Wireshark shot when stuck happen

最佳答案

我已经在家里测试过(代码贴在这里),在另一个WIFI环境下,它工作正常。唯一不同的是WIFI环境,所以我想可能是我们公司的WIFI网络设置导致了这个问题。

关于Android 套接字每 20 秒卡住一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51758450/

相关文章:

node.js - 向客户端发送数据(数据是具有大原型(prototype)的对象)

android - 在 Android 中获取 "Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy"

java - 如何在 Canvas 上以原始方式绘制更多矩形?

c++ - 为什么结构体的 sizeof 不等于每个成员的 sizeof 之和?

c - C 中带有终止符的动态数组

java - 在JAVA中通过不可靠的网络发送消息

android - GestureDetectorCompat 不工作?

安卓GPS芯片厂商

c - 如何在C中获取字符串的最后一部分

java - 监听套接字必须在线程中运行吗?