Pracuję nad aplikacją, która zawiera kilka gniazd serwera, z których każdy działa w unikalnym wątku.
Zewnętrzne narzędzie (skrypt) jest wywoływane przez jeden z wątków. Ten skrypt wywołuje narzędzie (klienta), które wysyła wiadomość do jednego z gniazd serwera.socket() zwraca 0 w aplikacji serwera klienta C
Początkowo używałem system()
do wykonania tego zewnętrznego skryptu, ale nie mogliśmy tego użyć, ponieważ musieliśmy upewnić się, że gniazda serwera zostały zamknięte w potomku, które zostało rozwidlone w celu wykonania zewnętrznego skryptu.
Sam teraz nazywam się fork()
i . I fork()
, a następnie w systemie podrzędnym zamykam wszystkie gniazda serwera, a następnie wywołuję execvp()
, aby wykonać skrypt.
Teraz wszystko działa dobrze. Problem polega na tym, że czasami skrypt zgłasza błędy w aplikacji serwera. Skrypt wysyła te błędy, wywołując inną aplikację (klienta), która otwiera gniazdo TCP i wysyła odpowiednie dane. Mój problem polega na tym, że aplikacja kliencka otrzymuje wartość 0
zwróconą przez wywołanie systemowe socket()
.
UWAGA: Ten parametr występuje TYLKO po wywołaniu skryptu/aplikacji klienckiej przy użyciu mojej funkcji forkExec(). Jeśli skrypt/aplikacja klienta jest wywoływana ręcznie, wywołanie socket()
działa poprawnie i wszystko działa poprawnie.
Na podstawie tych informacji podejrzewam, że jest to coś w moim fork() kod execvp() poniżej ... Wszelkie pomysły?
void forkExec()
{
int stat;
stat = fork();
if (stat < 0)
{
printf("Error forking child: %s", strerror(errno));
}
else if (stat == 0)
{
char *progArgs[3];
/*
* First, close the file descriptors that the child
* shouldn't keep open
*/
close(ServerFd);
close(XMLSocket);
close(ClientFd);
close(EventSocket);
close(monitorSocket);
/* build the arguments for script */
progArgs[0] = calloc(1, strlen("/path_to_script")+1);
strcpy(progArgs[0], "/path_to_script");
progArgs[1] = calloc(1, strlen(arg)+1);
strcpy(progArgs[1], arg);
progArgs[2] = NULL; /* Array of args must be NULL terminated for execvp() */
/* launch the script */
stat = execvp(progArgs[0], progArgs);
if (stat != 0)
{
printf("Error executing script: '%s' '%s' : %s", progArgs[0], progArgs[1], strerror(errno));
}
free(progArgs[0]);
free(progArgs[1]);
exit(0);
}
return;
}
Client kod aplikacji:
static int connectToServer(void)
{
int socketFD = 0;
int status;
struct sockaddr_in address;
struct hostent* hostAddr = gethostbyname("localhost");
socketFD = socket(PF_INET, SOCK_STREAM, 0);
Powyższe powraca połączeń 0.
if (socketFD < 0)
{
fprintf(stderr, "%s-%d: Failed to create socket: %s",
__func__, __LINE__, strerror(errno));
return (-1);
}
memset(&address, 0, sizeof(struct sockaddr));
address.sin_family = AF_INET;
memcpy(&(address.sin_addr.s_addr), hostAddr->h_addr, hostAddr->h_length);
address.sin_port = htons(POLLING_SERVER_PORT);
status = connect(socketFD, (struct sockaddr *)&address, sizeof(address));
if (status < 0)
{
if (errno != ECONNREFUSED)
{
fprintf(stderr, "%s-%d: Failed to connect to server socket: %s",
__func__, __LINE__, strerror(errno));
}
else
{
fprintf(stderr, "%s-%d: Server not yet available...%s",
__func__, __LINE__, strerror(errno));
close(socketFD);
socketFD = 0;
}
}
return socketFD;
}
FYI
OS: Linux
Arch: arm32
Kernel: 2.6.26
Czy możesz wysłać kod, który wywołuje socket(), proszę? – abc
Nie mam jeszcze pojęcia, co się dzieje z twoim gniazdem. Może ci pomóc, jeśli powiem, że możesz znacznie łatwiej wypowiadać argumenty: const char * progArgs [] = {"/ path_to_script", arg, NULL}; - Nie trzeba przydzielać i kopiować, wszystko, czego potrzebujesz, to tablica z odpowiednimi wskaźnikami w czasie, gdy wywołujesz execvp. – VoidPointer