Порт сервера не возвращается к прослушиванию и находится в состоянии closed_wait из-за запуска приложения-демона с клиента

Ниже приведен основной код клиента и сервера.
В то время как я пытаюсь запустить appliaction (который должен продолжать работать в машине, когда мы отправляем сообщение на сервер) во время вызова connect.
использование system (/ bin / myApplication) в клиентском коде (это в основном простой исполняемый файл c с бесконечным циклом, предполагая, что мое приложение должно быть запущено);
Как только я запускаю приложение, сервер находится в состоянии CLOSED_WAIT, и он возвращается, чтобы прослушать, только если я остановлю это приложение.
Проблема заключается в том, что серверный сокет находится в состоянии CLOSED_WAIT. Есть ли способ, чтобы это приложение продолжало работать как отдельный процесс, и сервер снова находился бы в состоянии прослушивания.
Код клиента: есть системная команда после read.and запускает приложение (в основном это исполняемый файл c с бесконечным циклом while)

#include <sys/types.h>
#include <sys/socket.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;
}

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(&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], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}

if( connect(sockfd, (struct sockaddr *)&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;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
system(/bin/myApplication);
if(n < 0)
{
printf("\n Read error \n");
}

return 0;

Код сервера:

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(&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*)&serv_addr, sizeof(serv_addr));

listen(listenfd, 10);

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

ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));

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

My Sample C File, который я пытаюсь выполнить, используя системную команду в клиенте
код. с

gcc Sample.c -o myApplication

int main(int argc, char *argv[])
{

while(1)

{

}
}

Я попытался использовать fork, но все еще сокет находится в том же состоянии, есть ли в любом случае, что это приложение работает отдельно и не влияет на сокет, и при этом это не зависит от родительского процесса (Сервер здесь).

0

Решение

Ваше клиентское приложение никогда не закрывает сокет, и поскольку образец приложения, которое вы создаете, зацикливается навсегда, клиент никогда не завершает работу. Это оставляет состояние соединения TCP висящим с обеих сторон.

В клиенте попробуйте закрыть сокет перед порождением примера приложения.

Кроме того, я думаю, что вы не уверены в состояниях TCP. Конечный компонент сервера в состоянии LISTEN не переходит в CLOSE_WAIT и обратно. Конечная точка LISTEN (сокет, который вы назвали listen() на) останется в этом состоянии до закрытия. Подключенная конечная точка (сокет, возвращаемый accept()) будет переходить через различные состояния в течение своей жизни.

Если вы используете netstat Команда, чтобы увидеть состояния, обязательно используйте -a флаг для отображения конечных точек прослушивания, а также.

0

Другие решения

Я добавил строку ниже перед системной командой

fcntl(sockfd, F_SETFD, fcntl(sockfd, F_GETFD) | FD_CLOEXEC);

И изменил код моего клиента на

#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>
#include <sys/socket.h>
#include <fcntl.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;
}

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(&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], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}

if( connect(sockfd, (struct sockaddr *)&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;
if(fputs(recvBuff, stdout) == EOF)
printf("\n Error : Fputs error\n");
}

}

fcntl(sockfd, F_SETFD, fcntl(sockfd, F_GETFD) | FD_CLOEXEC);

system("/software/itcsm/itcsm/refasset/bin/start_script.sh 1");

if(n < 0)
{
printf("\n Read error \n");
}
printf("\n after system \n");

return 0;
}

По умолчанию всякий раз, когда мы разветвляем процесс (что делает системная команда), потомок наследует все файловые дескрипторы родителя. Если дочерний элемент не нуждается в этих дескрипторах, он ДОЛЖЕН добровольно закрыть их по файловому дескриптору, используя fcntl (sockfd, F_SETFD, fcntl (sockfd, F_GETFD) | FD_CLOEXEC);

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector