简体   繁体   中英

Receive latest packet in udp server - C

UDP server is receiving packets with the select system call. And I want to receive the latest packet from each UDP-client. (I also want to listen to multiple UDP client packets).

The codes of my simple UDP-server:

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));
                }
            }
        }
    }
}

The best way to handle this is to have the sender put a sequence number in each packet. For each packet that is sent out, the sequence number increases by 1.

On the receiver side, you would keep track of the counter of the last packet you received. If the next packet that comes in has a larger counter, it's the latest. If it's not larger, it's an older packet and you can handle it in an appropriate manner for your application.

Also, you should rename you recv variable to something like recv_len . recv is the name of a socket function that would be masked by this variable definition.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM