TCP 套接字在 LTE 上消失

TCP 套接字在 LTE 上消失

我有大约 25 个音频流客户端构建在 i.mx6 arm 平台上,运行 linux 版本 4.3.0-rc2-00019-gbcee19f-dirty #36 SMP Tue Feb 9 15:27:51 EST 2016 armv7l

我发现在阿尔伯塔省的 4g lte(mbr1516)上的两个特定单元上,插座每隔几分钟就会断电一次,而网络上其他基于 Windows 的流媒体客户端则在同一时间段内保持工作。

我确实怀疑 4g 蜂窝防火墙正在干扰这些数据包,但却无法确定到底是什么,也不知道如何深入研究。

18:11:35 至 18:12:06 的整个时间段内,其他外部 IP 均有进出流量。我认为该服务器是 linode 设置,不太可能是服务器端问题。

网络配置是Streaming_Box->4G_LTE_Router->internet->Icecast_Server

补充 1:此客户端流媒体设备可以发送多个流,因此如果我发送两个并排的流,一个开放 http,另一个通过 openvpn,则 http 会中断,而隧道 http 不会。

客户端捕获 服务器捕获 套接字处理代码

void * StreamingThread1(void * ptr) {
    int a, b, SendCount;
    ssize_t BytesSent;
    int Burst = 1;
    time_t timer, timercomp, OnDelay;
    time(&timer);
    time(&OnDelay);
    unsigned char * RxBuff = malloc(5000);
    unsigned char * OutBuff = malloc(65535);
    if (RxBuff == NULL || OutBuff == NULL) {
        MyLog("StreamThread1 Unable to allocate RxBuff or OutBuff\n");
        StartupError(50);
    }
    Control.StreamConnected1 = 0;
    Control.StreamConnectErr = StrmErr_None;
    signal(SIGPIPE, SIG_IGN);
    int sockfd = -1;
    struct hostent *server;
    struct sockaddr_in serv_addr;
    struct timeval tv;
    int BuffSize = 65535;
    socklen_t optlen = 4;
    tv.tv_sec = 10;
    tv.tv_usec = 0;
    while (1) {
        usleep(10000); //Give threads a breather
        if (Control.RestartStream1) {
            time(&timer);
            Control.RestartStream1 = 0;
            if (sockfd > -1) {
                close(sockfd);
                sockfd = -1;
            }
            sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
            if (sockfd == -1) {
                Debug("Unable to create socket %s\n", strerror(errno));
                goto ExitConnect;
            }
            setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof (struct timeval));
            setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *) &tv, sizeof (struct timeval));
            setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &BuffSize, optlen);
            Burst = 1;
            server = gethostbyname((char*) StreamParams.URL1);
            if (server == NULL) {
                Debug("Error finding host %s\n", StreamParams.URL1);
                Control.StreamConnectErr = StrmErr_NoHost;
            } else {
                bzero((char *) &serv_addr, sizeof (serv_addr));
                serv_addr.sin_family = AF_INET;
                bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length);
                serv_addr.sin_port = htons(StreamParams.Port1);
                Control.StreamConnected1 = connect(sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) != -1;
                if (!Control.StreamConnected1) {
                    Debug("ERROR, unable to connect to %s : %i : %i\n", StreamParams.URL1, StreamParams.Port1, errno);
                    Control.StreamConnectErr = StrmErr_NoConnect;
                    goto ExitConnect;
                } else {
                    Debug("Connected to %s : %i\n", StreamParams.URL1, StreamParams.Port1);
                }
                unsigned char* Message = BuildLogin(0);
                Control.StreamConnected1 = sendto(sockfd, Message, strlen(Message), MSG_NOSIGNAL, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) > -1;
                if (!Control.StreamConnected1) {
                    Debug("ERROR, unable to write message to %s : %i\n", StreamParams.URL1, StreamParams.Port1);
                    free(Message);
                    Control.StreamConnectErr = StrmErr_NoWrite;
                    goto ExitConnect;
                } else {
                    Debug("Login information sent to %s : %i\n", StreamParams.URL1, StreamParams.Port1);
                    free(Message);
                }
                a = recv_catch_eintr(sockfd, RxBuff, 5000, MSG_NOSIGNAL, 10000);
                if (a <= 0) {
                    Control.StreamConnected1 = 0;
                    Debug("Unable to authenticate, nothing received %s\n", strerror(errno));
                } else {
                    if (strstr((const unsigned char*) RxBuff, "HTTP/1.0 200 OK") != NULL) {
                        Debug("Authentication successfull\n");
                        Control.AuthError1 = 0;
                    } else {
                        Control.StreamConnected1 = 0;
                        Control.AuthError1 = 1;
                        Control.StreamConnectErr = StrmErr_Auth;
                        Debug("Authentication Error\n");
                    }
                }
            }
        }
ExitConnect:
        if (Control.StreamConnected1 && sockfd > -1) {
            if (Burst) {
                b = LameParams.BitRate * 3 * 1000 / 8;
                if (b > AudioBuffSize - 1024) {
                    b = AudioBuffSize - 1024;
                }
                unsigned short Diff = AudioHeadPtr - AudioTailPtr1;
                if (Diff > b) {
                    Burst = 0;
                    for (a = 0; a < b; a++) {
                        OutBuff[a] = AudioBuffer[AudioTailPtr1++];
                    }
                    Control.StreamConnected1 = send(sockfd, OutBuff, b, 0) == b;
                    Debug("Sent %i Burst\n", b);
                }
            } else {
                SendCount = 0;
                while (AudioTailPtr1 != AudioHeadPtr && a < sizeof (AudioBuffer) - 1024) {
                    OutBuff[SendCount++] = AudioBuffer[AudioTailPtr1++];
                }
                if (SendCount > 0 && sockfd > -1) {
                    BytesSent = send(sockfd, OutBuff, SendCount, MSG_NOSIGNAL);
                    Control.StreamConnected1 = (BytesSent > 0);
                    Control.StreamConnectErr = StrmErr_None;
                    if (BytesSent != SendCount) {
                        Debug("Tried %i sent %i\n", SendCount, BytesSent);
                        AudioTailPtr1 -= (SendCount - BytesSent);
                    }
                    if (BytesSent < 0) {
                        AudioTailPtr1 -= SendCount;
                        Debug("Lost Connection errno %s\n", strerror(errno));
                        Control.StreamConnectErr = StrmErr_LostConn;
                        Control.StreamConnected1 = 0;
                        close(sockfd);
                        sockfd = -1;
                    }
                }
            }
        } else {
            //Wait 5 then try again.
            if (sockfd > -1) {
                Debug("Closing socket %i\n", sockfd);
                close(sockfd);
                sockfd = -1;
            }
            time(&timercomp);
            if (timercomp - timer >= 5) {
                Control.RestartStream1 = 1;
                Debug("Stream restart at %i\n", timercomp);
            }
        }
    }
}

相关内容