Неужели мой код вызвал слишком много сокетов? - PullRequest
0 голосов
/ 29 сентября 2019

Я написал сетевой пинг-код ICMP на C, ниже мой код, он пытался пинговать тысячи IP-адресов, но через несколько дней общее количество открытых сокетов увеличилось до 35K. Где я должен освободить мою розетку, пожалуйста.

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 Ответ

1 голос
/ 29 сентября 2019

Вы должны закрыть сокет в конце функции. После цикла for.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...