#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");
я обнаружил, что количество сокетов увеличилось, поэтому я думаю, что это та же проблема.