我正在研究一個包含多個服務器套接字的應用程序,每個服務器套接字在獨特的線程中運行。
一個外部實用程序(腳本)由其中一個線程調用。該腳本調用將消息發送到其中一個服務器套接字的實用程序(客戶端)。在C客戶端服務器應用程序中,socket()返回0
最初,我使用system()
來執行這個外部腳本,但是我們不能使用它,因爲我們必須確保服務器套接字在被分叉以執行外部腳本的孩子中關閉。
我現在自己撥打fork()
和execvp()
。我fork()
然後在小孩我關閉所有的服務器套接字,然後調用execvp()
執行該腳本。
現在,所有這些工作正常。問題是有時腳本會向服務器應用程序報告錯誤。該腳本通過調用另一個打開TCP套接字併發送適當數據的應用程序(客戶端)來發送這些錯誤。我的問題是客戶端應用程序獲得socket()
系統調用返回的值0
。
注意:只有在使用我的forkExec()函數調用腳本/客戶端應用程序時,纔會發生此問題。如果手動調用腳本/客戶端應用程序,則socket()
調用執行得當,並且事情正常工作。
基於這些信息我懷疑這是在我的fork()execvp()代碼下面的東西...任何想法?
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;
}
客戶端應用程序代碼:
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);
上述呼叫返回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
操作系統:Linux
拱:ARM32
內核:2.6.26
你能發佈調用socket()的代碼嗎? – abc 2010-01-25 20:00:13
不知道你的套接字發生了什麼。如果我指出你可以更簡單地聲明你的參數,可能對你有幫助:const char * progArgs [] = {「/ path_to_script」,arg,NULL}; - 無需分配和複製,只需在調用execvp時使用正確指針的數組即可。 – VoidPointer 2010-01-25 20:12:34