Невозможно создать сокет после создания 1020 раз для связи

#c #linux #sockets #gcc

#c #linux #сокеты #gcc

Вопрос:

Я следую руководству по программированию сокетов по этой ссылке Программирование сокетов. и пытаюсь разработать приложение, в котором клиент будет получать сетевое время с сервера и печатать время. Вот как работает программа-

Сервер ожидает входящего соединения, и пока клиент пытается соединиться с сервером, сервер принимает соединение, и сервер отправляет время клиенту. После получения через клиент сокета выведите время.

После каждой отправки сообщения клиенту сервер закрывает соединение и ожидает следующего. Клиент может взаимодействовать с сервером 1020 раз. Если я пытаюсь обмениваться данными более 1020 раз с клиента на сервер, то я получаю ошибку — Не удается создать сокет

Я пытаюсь разработать приложение, в котором клиент может взаимодействовать с сервером бесконечное количество раз или по крайней мере 20000 раз.

Я подозреваю, что, возможно, память не освобождается при создании сокета на стороне клиента.

 Sample output :

counter=1017 Sun Jul  6 03:19:48 2014
counter=1018 Sun Jul  6 03:19:48 2014
counter=1019 Sun Jul  6 03:19:48 2014
counter=1020 Sun Jul  6 03:19:48 2014
  

Ошибка: Не удалось создать сокет (ПОЧЕМУ??)

Вот мой код

Server.c

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

int main(int argc, char *argv[])
{
    int listenfd = 0, connfd = 0;
    struct sockaddr_in serv_addr; 

    char sendBuff[1025];
    time_t ticks; 

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    memset(amp;serv_addr, '0', sizeof(serv_addr));
    memset(sendBuff, '0', sizeof(sendBuff)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(5000); 

    bind(listenfd, (struct sockaddr*)amp;serv_addr, sizeof(serv_addr)); 

    listen(listenfd, 10); 

    while(1)
    {
        connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 

        ticks = time(NULL);
        snprintf(sendBuff, sizeof(sendBuff), "%.24srn", ctime(amp;ticks));
        write(connfd, sendBuff, strlen(sendBuff)); 

        close(connfd);
      //  sleep(1);
     }
}
  

Client.c

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

int main(int argc, char *argv[])
{
    int sockfd = 0, n = 0;
    char recvBuff[1024];
    struct sockaddr_in serv_addr; 

    if(argc != 2)
    {
        printf("n Usage: %s <ip of server> n",argv[0]);
        return 1;
    } 

int counter=0;

while(counter <2000)
{
    memset(recvBuff, '0',sizeof(recvBuff));
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("n Error : Could not create socket n");
        return 1;
    } 

    memset(amp;serv_addr, '0', sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(5000); 

    if(inet_pton(AF_INET, argv[1], amp;serv_addr.sin_addr)<=0)
    {
        printf("n inet_pton error occuredn");
        return 1;
    } 

    if( connect(sockfd, (struct sockaddr *)amp;serv_addr, sizeof(serv_addr)) < 0)
    {
       printf("n Error : Connect Failed n");
       return 1;
    } 

    while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
    {
        recvBuff[n] = 0;
        printf("counter=%d ",counter);
        fputs(recvBuff, stdout);
       /*
        if(fputs(recvBuff, stdout) == EOF)
        {
            printf("n Error : Fputs errorn");
        }
        */ 
    } 
    
counter  ;
}
    if(n < 0)
    {
        printf("n Read error n");
    } 

    return 0;
}
  

Я использую gcc под Ubuntu. Любая помощь для понимания причины, устранения неполадок и запуска программы примерно за 20000 будет высоко оценена. Заранее спасибо.

Комментарии:

1. Взгляните на setsockopt() и SO_REUSEADDR тоже.

Ответ №1:

Вы не закрываете сокет вашего клиента после его использования. Вам нужна эта строка в вашем клиентском коде:

 close(sockfd);
  

После вашего цикла while.

Ответ №2:

Похоже, у вас произошла утечка сокета в вашем клиентском коде. Вы создаете сокеты внутри вашего внешнего цикла, но вы никогда не закрываете их. Попробуйте добавить close(sockfd); в конец вашего внешнего цикла и во все точки, где вы прерываете его или возвращаетесь из него.

Ответ №3:

Поскольку вы используете один и тот же клиент для подключения к серверу, вам не нужно начинать процесс socket amp; connect заново, вы можете заблокировать клиент, пока не получите некоторые данные с сервера. В противном случае вы ненужно тратите много ресурсов ядра, и вы закрываетесь и открываетесь на очень быстрой фазе, что не очень хорошая идея!

Ответ №4:

У меня та же проблема. В моей ситуации, после fopen("/proc/net/route" , "r"); , я забыл fclose() .

После fopen("/proc/net/route" , "r"); я обнаружил, что количество сокетов увеличилось, поэтому я думаю, что это та же проблема.