Android Socket卡死每20秒

时间:2018-08-09 03:38:45

标签: android c sockets tcp

我在一个动作游戏中使用TCP套接字连接,我们使用锁步同步,客户端每秒将接收20-40个数据包。当游戏在PC上运行时效果很好,但是在Android设备上运行时,插槽每20秒就会卡住

Server sends 5 packets per second

我尝试使用Unity3D的C#套接字,Android Java套接字和Android本机C套接字以及阻塞/非阻塞模式,每个数据包的大小为(大/小(1byte / 100byte)),每个数据包的减少/更多(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

1 个答案:

答案 0 :(得分:0)

我已经在家里和另一个WIFI环境中对其进行了测试(代码在此处发布),它工作正常。唯一的区别是WIFI环境,所以我认为也许我们公司的WIFI网络设置会导致此问题。