C UDP组播接收包丢失

标签 c linux sockets udp multicast

我编写了一个 C 程序来接收 UDP 多播数据包,并且它可以工作。然而,当程序运行几秒钟时,丢包的情况经常发生。当我按Ctrl + C终止程序并重新启动它时,它会收到大部分数据包,但几秒钟后就会发生数据包丢失。这很奇怪,到底是什么问题呢?这是我的 C 代码。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>

#include <fcntl.h>
#include <sys/ioctl.h>
#include <android/log.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>

#define BUF_SIZE 4

int mjpeg_main(){
    int sockfd;
    struct sockaddr_in localSock;
    struct ip_mreq group;
    char buf[BUF_SIZE];
    int len = sizeof(localSock);

/* Create a datagram socket on which to receive. */
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
    perror("Can't create socket!");
    exit(1);
}

/* Enable SO_REUSEADDR to allow multiple instances of this */
/* application to receive copies of the multicast datagrams. */
int reuse = 1;
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
{
    perror("Setting SO_REUSEADDR error");
    close(sockfd);
    exit(1);
}

int n = 1024 * 1024;
if (setsockopt(sockfd,SOL_SOCKET,SO_RCVBUFFORCE,(const char*)&n, sizeof(int)) == -1)
{
  // deal with failure, or ignore if you can live with the default size
}



/* Bind to the proper port number with the IP address */
/* specified as INADDR_ANY. */
memset((char *) &localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(2068);
localSock.sin_addr.s_addr = INADDR_ANY;
if(bind(sockfd, (struct sockaddr*)&localSock, sizeof(localSock)))
{
    perror("Binding datagram socket error");
    close(sockfd);
    exit(1);
}

/* Join the multicast group 239.100.15.101 on the local 203.106.93.94 */
/* interface. Note that this IP_ADD_MEMBERSHIP option must be */
/* called for each local interface over which the multicast */
/* datagrams are to be received. */
group.imr_multiaddr.s_addr = inet_addr("239.100.15.101");
group.imr_interface.s_addr = inet_addr("10.100.15.115");
if(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0)
{
    perror("Adding multicast group error");
    close(sockfd);
    exit(1);
}


printf("Start to receive!n");
__android_log_print(ANDROID_LOG_INFO,"mjpeg","mjpeg start !!");

//Wait for connect
while(1)
{
    memset(buf, 0, sizeof(buf));
    int z = recvfrom(sockfd,                      // Socket
                     buf,                         // Receiving buffer
                     sizeof buf,                  // Max recv buf size
                     0,                           // Flags: no options
                     (struct sockaddr *)&localSock,// Addr
                     &len);                       // Addr len, in & out
    if ( z < 0 ) 
    {
        perror("recv");
        exit(1);
    }

    printf("Frame: %02X:%02X, Sequence: %02X:%02X\n", buf[0], buf[1], buf[2], buf[3]);
}

close(sockfd);
return 0;
}

而且,这就是结果。发送端是一个硬件,一个帧包含很多序列。序列号将依次增加。

Frame: 09:1F, Sequence: 00:00
Frame: 09:1F, Sequence: 00:01
Frame: 09:1F, Sequence: 00:02
Frame: 09:1F, Sequence: 00:03
Frame: 09:1F, Sequence: 00:04
Frame: 09:1F, Sequence: 00:05
Frame: 09:1F, Sequence: 00:06
Frame: 09:1F, Sequence: 00:07
Frame: 09:1F, Sequence: 00:08
Frame: 09:1F, Sequence: 00:09
Frame: 09:1F, Sequence: 00:0A
Frame: 09:1F, Sequence: 00:0B
Frame: 09:1F, Sequence: 00:0C
Frame: 09:1F, Sequence: 00:0D
Frame: 09:1F, Sequence: 00:0E
Frame: 09:1F, Sequence: 00:0F
Frame: 09:1F, Sequence: 00:10
Frame: 09:1F, Sequence: 00:11
Frame: 09:1F, Sequence: 00:12
Frame: 09:1F, Sequence: 00:13
Frame: 09:1F, Sequence: 00:14
Frame: 09:1F, Sequence: 00:15
Frame: 09:1F, Sequence: 00:16
Frame: 09:1F, Sequence: 00:17
Frame: 09:1F, Sequence: 00:18
Frame: 09:1F, Sequence: 00:19
Frame: 09:1F, Sequence: 00:1A
Frame: 09:1F, Sequence: 00:1B
Frame: 09:1F, Sequence: 00:1C
Frame: 09:1F, Sequence: 00:1D
Frame: 09:1F, Sequence: 00:1E
Frame: 09:1F, Sequence: 00:1F
Frame: 09:1F, Sequence: 00:20
Frame: 09:1F, Sequence: 00:21
Frame: 09:1F, Sequence: 00:22
Frame: 09:1F, Sequence: 00:23
Frame: 09:1F, Sequence: 00:24
Frame: 09:1F, Sequence: 00:25
Frame: 09:1F, Sequence: 00:26
Frame: 09:1F, Sequence: 00:27
Frame: 09:1F, Sequence: 00:28
Frame: 09:1F, Sequence: 00:29
Frame: 09:1F, Sequence: 00:2A
Frame: 09:1F, Sequence: 00:2B
Frame: 09:1F, Sequence: 00:2C
Frame: 09:1F, Sequence: 00:2D
Frame: 09:1F, Sequence: 00:2E
Frame: 09:1F, Sequence: 00:2F
Frame: 09:1F, Sequence: 00:30
Frame: 09:1F, Sequence: 00:31
Frame: 09:1F, Sequence: 00:32
Frame: 09:1F, Sequence: 00:33
Frame: 09:1F, Sequence: 00:34
Frame: 09:1F, Sequence: 00:35
Frame: 09:1F, Sequence: 00:36
Frame: 09:1F, Sequence: 00:37
Frame: 09:1F, Sequence: 00:38
Frame: 09:1F, Sequence: 00:39
Frame: 09:1F, Sequence: 00:3A
Frame: 09:1F, Sequence: 00:3B
Frame: 09:1F, Sequence: 00:3C
Frame: 09:1F, Sequence: 00:3D
Frame: 09:1F, Sequence: 00:3E
Frame: 09:1F, Sequence: 00:3F
Frame: 09:1F, Sequence: 00:40
Frame: 09:1F, Sequence: 00:41
Frame: 09:1F, Sequence: 00:42
Frame: 09:1F, Sequence: 00:43
Frame: 09:1F, Sequence: 00:44
Frame: 09:1F, Sequence: 00:45
Frame: 09:1F, Sequence: 00:46
Frame: 09:1F, Sequence: 00:47
Frame: 09:1F, Sequence: 00:48
Frame: 09:1F, Sequence: 00:49
Frame: 09:1F, Sequence: 00:4A
Frame: 09:1F, Sequence: 00:4B
Frame: 09:1F, Sequence: 00:4C
Frame: 09:1F, Sequence: 00:4D
Frame: 09:1F, Sequence: 80:4E
Frame: 09:20, Sequence: 00:00
Frame: 09:20, Sequence: 00:01
Frame: 09:20, Sequence: 00:02
Frame: 09:20, Sequence: 00:03
Frame: 09:20, Sequence: 00:04
Frame: 09:20, Sequence: 00:05
Frame: 09:20, Sequence: 00:06
Frame: 09:20, Sequence: 00:07
Frame: 09:20, Sequence: 00:08
Frame: 09:20, Sequence: 00:09
Frame: 09:20, Sequence: 00:0A
Frame: 09:20, Sequence: 00:0B
Frame: 09:20, Sequence: 00:0C
Frame: 09:20, Sequence: 00:0D
Frame: 09:20, Sequence: 00:0E
Frame: 09:20, Sequence: 00:0F
Frame: 09:20, Sequence: 00:10
Frame: 09:20, Sequence: 00:11
Frame: 09:20, Sequence: 00:12
Frame: 09:20, Sequence: 00:13
Frame: 09:20, Sequence: 00:14
Frame: 09:20, Sequence: 00:15
Frame: 09:20, Sequence: 00:16
Frame: 09:20, Sequence: 00:17
Frame: 09:20, Sequence: 00:18
Frame: 09:20, Sequence: 00:19
Frame: 09:20, Sequence: 00:1A
Frame: 09:20, Sequence: 00:1B
Frame: 09:20, Sequence: 00:1C
Frame: 09:20, Sequence: 00:1D
Frame: 09:20, Sequence: 00:1E
Frame: 09:20, Sequence: 00:1F
Frame: 09:20, Sequence: 00:20
Frame: 09:20, Sequence: 00:21
Frame: 09:20, Sequence: 00:22
Frame: 09:20, Sequence: 00:23
Frame: 09:20, Sequence: 00:24
Frame: 09:20, Sequence: 00:25
Frame: 09:20, Sequence: 00:26
Frame: 09:20, Sequence: 00:27
Frame: 09:20, Sequence: 00:28
Frame: 09:20, Sequence: 00:29
Frame: 09:20, Sequence: 00:2E
Frame: 09:20, Sequence: 00:31
Frame: 09:20, Sequence: 00:37
Frame: 09:20, Sequence: 00:3B
Frame: 09:20, Sequence: 00:3D
Frame: 09:20, Sequence: 00:3F
Frame: 09:20, Sequence: 00:41
Frame: 09:20, Sequence: 00:42
Frame: 09:20, Sequence: 00:44
Frame: 09:20, Sequence: 00:46
Frame: 09:20, Sequence: 00:4B
Frame: 09:20, Sequence: 80:4E
Frame: 09:21, Sequence: 00:00
Frame: 09:21, Sequence: 00:01

start packet lost...

Frame: 09:21, Sequence: 00:06
Frame: 09:21, Sequence: 00:10
Frame: 09:21, Sequence: 00:1C
Frame: 09:21, Sequence: 00:25
Frame: 09:21, Sequence: 00:2F
Frame: 09:21, Sequence: 00:35
Frame: 09:21, Sequence: 00:3B
Frame: 09:21, Sequence: 00:3C
Frame: 09:21, Sequence: 00:3E
Frame: 09:21, Sequence: 00:40
Frame: 09:21, Sequence: 00:42
Frame: 09:21, Sequence: 00:43
Frame: 09:21, Sequence: 00:45
Frame: 09:21, Sequence: 00:47
Frame: 09:21, Sequence: 00:4D
Frame: 09:22, Sequence: 00:01
Frame: 09:22, Sequence: 00:05
Frame: 09:22, Sequence: 00:0D
Frame: 09:22, Sequence: 00:1B
Frame: 09:22, Sequence: 00:23
Frame: 09:22, Sequence: 00:2F
Frame: 09:22, Sequence: 00:34
Frame: 09:22, Sequence: 00:3A
Frame: 09:22, Sequence: 00:3C
Frame: 09:22, Sequence: 00:3E
Frame: 09:22, Sequence: 00:40
Frame: 09:22, Sequence: 00:41
Frame: 09:22, Sequence: 00:43
Frame: 09:22, Sequence: 00:45
Frame: 09:22, Sequence: 00:47
Frame: 09:22, Sequence: 00:4D
Frame: 09:23, Sequence: 00:01
Frame: 09:23, Sequence: 00:04
Frame: 09:23, Sequence: 00:0A
Frame: 09:23, Sequence: 00:19
Frame: 09:23, Sequence: 00:20
Frame: 09:23, Sequence: 00:2E
Frame: 09:23, Sequence: 00:32
Frame: 09:23, Sequence: 00:39
Frame: 09:23, Sequence: 00:3C
Frame: 09:23, Sequence: 00:3E
Frame: 09:23, Sequence: 00:3F
Frame: 09:23, Sequence: 00:41
Frame: 09:23, Sequence: 00:43
Frame: 09:23, Sequence: 00:45
Frame: 09:23, Sequence: 00:46
Frame: 09:23, Sequence: 00:4D

最佳答案

问题已经解决了。原因是我们的PHY使用的是外部晶振,内核时钟配置不正确。

关于C UDP组播接收包丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28081907/

相关文章:

c++ - C 和 C++ : Difference between Casting and Conversion

c++ - 将 int 转换为 ASCII 字符

linux - Docker 构建失败并显示 "RUN: command not found"

sockets - Windows Phone P2P TCP/IP 连接

c - 包含 header 时出现多重定义错误(How to add header in c?)

python - 将 C 函数的指针参数与 python 脚本中的 ctype 参数链接起来

linux - 使用 wget 下载 html 页面中的嵌入链接

linux - 如果执行 shell 失败,jenkins 构建不会失败

屏幕变黑后,Java Android 套接字立即被杀死

python - 套接字卡在循环中