当前位置: 首页 > 知识库问答 >
问题:

在udp服务器中接收最新数据包-C

全昊焜
2023-03-14

UDP服务器正在接收带有选择系统调用的数据包。我想从每个UDP客户端接收最新的数据包。(我还想监听多个UDP客户端数据包)。

我的简单UDP服务器的代码:

int main(void) {
    int fd;
    int port = 5678;
    char buffer[1024];
    fd_set readfs;
    socklen_t client_length;
    struct timeval timeout_interval;
    struct sockaddr_in6 server_addr;
    struct sockaddr_in6 client_addr;
    int result;
    int recv;
    char client_addr_ipv6[100];

    fd = socket(PF_INET6, SOCK_DGRAM, 0);
    printf(" \e[1m \e[34m ---------------------------------------- \n--------------------  UDP SERVER --------------------\n   \e[39m \e[0m \n");
    printf("Process: \e[34m %d \e[49m Port ..\n", port);

    if (fd < 0) {
        printf("ERR: fd < 0");
    } else {
        memset(&server_addr, 0, sizeof(server_addr));
        server_addr.sin6_family = AF_INET6;
        server_addr.sin6_addr = in6addr_any;
        server_addr.sin6_port = htons(port);
        memset(&client_addr, 0, sizeof(client_addr));
        client_addr.sin6_family = AF_INET6;
        client_addr.sin6_addr = in6addr_any;
        client_addr.sin6_port = htons(port);

        if (bind(fd, (struct sockaddr *) &server_addr, sizeof(server_addr))
                >= 0) {
            printf("\e[1m INFO: \e[0m \e[34m Bind success.. \e[39m\n");

        } else {
            printf("Bind.");
            return -1;
        }
        for (;;) {
            FD_ZERO(&readfs);
            FD_SET(fd, &readfs);
            int max_fd = MAX(0, fd);
            timeout_interval.tv_sec = 3;
            timeout_interval.tv_usec = 50000000;

            result = select(max_fd + 1, &readfs, NULL, NULL, &timeout_interval);
            //printf("\n %d \t %d \n", result, fd);
            if (result < 0) {
                printf("ERR\n");
            } else if (result == 0) {
                printf("\nTimeout\n");
            } else {
                if (FD_ISSET(fd, &readfs)) {
                    client_length = sizeof(client_addr);
                    if ((recv = recvfrom(fd, buffer, sizeof(buffer), 0,
                                    (struct sockaddr *) &client_addr, &client_length))
                            < 0) {
                        printf("Recv-ERR!");
                        break;
                    }
                    inet_ntop(AF_INET6, &(client_addr.sin6_addr), client_addr_ipv6, 100);
                    //printf("Client IP/Port : %s  ",client_addr_ipv6);

                    printf("\n ------------------------------------------ \n");
                    printf("\e[1m Data: \e[0m  \e[32m %.*s \n Client IP/Port : \e[34m %s / %d \n\e[39m", recv, buffer,client_addr_ipv6,ntohs(client_addr.sin6_port));
                }
            }
        }
    }
}

共有1个答案

姬衡
2023-03-14

处理这个问题的最好方法是让发送者在每个数据包中放一个序列号。对于每发送一个数据包,序列号增加1。

在接收方,您将跟踪最后一个收到的数据包的计数器。如果下一个收到的包裹有一个更大的计数器,那么它是最新的。如果它不是更大,那么它是一个较旧的数据包,您可以为您的应用程序以适当的方式处理它。

另外,您应该将recv变量重命名为类似recv\u len的名称recv是将被此变量定义屏蔽的套接字函数的名称。

 类似资料:
  • 我有一个示例代码如下,套接字绑定到IP10.10.88.11和端口9876。我用下面的wireshark测试了2种情况。两台电脑都在同一个子网中。 从同一PC发送UDP数据包(10.10.88.11)-UDP服务器能够接收 从另一台电脑发送UDP数据包(10.10.88.10)-UDP服务器无法接收,但Wireshark(在10.10.88.11)能够捕获数据包 我在网上搜索过,但找不到解决办法。

  • 我不知道是网络配置还是我的软件出了问题。 这是监听代码: 奇怪的是,在wireshark上,我可以看到:数据包已从发送到,并且设备已对此数据包作出响应--来自的数据包已发送到。使用bind(0.0.0.0,端口)似乎不能涵盖。我迷路了,一点主意都没有。 ifconfig为:

  • 我有一个服务器正在,我正在尝试将数据从嵌入式设备发送到节点服务器。Wireshark正在显示收到的数据包 wireshark收到的数据包的图像 的标头校验和设置为。我想不出原因是什么。

  • 我们现有的软件定期向本地子网(X.X.X.255)上的特定端口(7125)广播UDP数据包。我们的监控软件运行在HP-UX(11.11)上,可以接收这些数据包,没有问题。然而,在将监控软件移植到Linux(RHEL6.1)之后,我们发现它并没有接收到广播数据包。tcpdump显示了到达Linux主机的数据包,但内核不会将它们发送给我们的软件。 我使用了几个Python2.x脚本,这些脚本模拟了监控

  • 我们有一个场景,(UDP客户端程序)向(UP服务器)发送UDP数据包 TCP在数据通信开始之前和结束之后执行握手。UDP没有。 那么,运行在上的应用程序失败的原因是否是上的服务器程序没有准备好(关闭)接收UDP数据包?