Escribí un código de ping ICMP de red en C, el siguiente es mi código, trató de hacer ping a miles de IP, pero después de unos días de ejecución, el número total de sockets abiertos aumentó a 35K. ¿Dónde debería soltar mi enchufe?

struct packet {
    struct icmphdr hdr;
    char msg[64 - sizeof(struct icmphdr)];
};
struct protoent *proto = NULL;

void ping(char *bindIp, char **ipArr, size_t ipCount) {
    //bindIp is the Ip in my machine for sending ip
    //ipArr is the destination Ips need to ping
    //ipCount is the total destination ip number
    const int val = 255;
    int i, sd, cnt = 1;
    struct sockaddr_in r_addr;
    r_addr.sin_family = AF_INET;
    r_addr.sin_addr.s_addr = inet_addr(bindIp);
    r_addr.sin_port = 0;

    sd = socket(PF_INET, SOCK_RAW, proto->p_proto);
    bind(sd, (struct sockaddr *) &r_addr, sizeof(r_addr));
    if (sd < 0) {
        perror("socket,you might need root/admin to operate\n");
        return;
    }
    if (setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0)
        perror("Set TTL option");
    if (fcntl(sd, F_SETFL, O_NONBLOCK) != 0)
        perror("Request nonblocking I/O");

    for (i = 0; i < ipCount; i++) {
        struct packet pckt;
        struct hostent *hname;
        hname = gethostbyname(ipArr[i]);
        struct sockaddr_in addr;
        proto = getprotobyname("ICMP");
        bzero(&addr, sizeof(addr));
        addr.sin_port = 0;

        addr.sin_family = hname->h_addrtype;
        addr.sin_addr.s_addr = *(long*) hname->h_addr;

        if(i%5==0){
            usleep(1001);
            if(i%50000==0){
                printf("ping oversea--i=%d,ip=%s\n",i,ipArr[i]);
            }
        }
        bzero(&pckt, sizeof(pckt));
        pckt.hdr.type = ICMP_ECHO;
        long currTs = current_timestamp();
        char buffer[20];
        sprintf(buffer,"_%lu", currTs);

        char *payload=concat(sendIp,buffer);

        strcpy(pckt.msg,payload);
        pckt.hdr.un.echo.id = 8899;
        pckt.hdr.un.echo.sequence = cnt++;
        pckt.hdr.checksum = checksum(&pckt, sizeof(pckt));
        free(payload);
        sendto(sd, &pckt, sizeof(pckt), 0, (struct sockaddr*) &addr,
                sizeof(addr));

    }
}
-1
Jack 29 sep. 2019 a las 23:16

1 respuesta

La mejor respuesta

Debe cerrar el zócalo al final de la función. Después del bucle for.

1
Florin Petriuc 29 sep. 2019 a las 20:22