在C客户端服务器应用程序中,socket()返回0

我正在处理一个包含多个服务器套接字的应用程序,每个服务器套接字在一个独特的线程中运行
一个外部实用程序(脚本)由其中一个线程调用。 该脚本调用将消息发送到其中一个服务器套接字的实用程序(客户端)。

最初,我使用system()来执行这个外部脚本,但是我们不能使用它,因为我们必须确保服务器套接字在被分执行外部脚本的孩子中被closures。
我现在自己调用fork()execvp() 。 我fork() ,然后在孩子我closures所有的服务器套接字,然后调用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
Arch:ARM32
内核:2.6.26

Solutions Collecting From Web of "在C客户端服务器应用程序中,socket()返回0"

socket()在出错时返回-1。

返回0意味着套接字()成功,并给你文件描述符0.我怀疑你关闭的文件描述符之一有文件描述符0,一旦它关闭,下一次调用一个函数分配一个文件描述符将返回fd 0因为它是可用的。

一个值为0的套接字是好的,这意味着stdin被关闭,这将使得fd 0可供重用 – 比如套接字。

机会是你在forkExec()子路径(XMLSocket / serverFd)等关闭的文件描述符之一)是fd 0。 这将启动fd 0关闭的孩子,当从命令行运行应用程序时不会发生这种情况,因为fd 0已经作为shell的stdin打开。

如果你想让你的套接字不是0,1或2(stdin / out / err),在所有的close()调用完成后,在你的forkExec()

 void reserve_tty() { int fd; for(fd=0; fd < 3; fd++) int nfd; nfd = open("/dev/null", O_RDWR); if(nfd<0) /* We're screwed. */ continue; if(nfd==fd) continue; dup2(nfd, fd); if(nfd > 2) close(nfd); } 

检查返回-1的套接字,这意味着发生错误。

不要忘记打电话给

 waitpid() 

“明显的问题模式”的结束。 我在这里假设了一下,但是你没有对fork()调用返回的pid做任何事情。 ( – :

正如另一个评论中提到的,你不应该关闭0,1或2(stdin / out / err),你可以放一个检查来确保你不关闭这些,所以它不会被指定为新的fd`当你请求一个新的套接字时