linux – socket()在C客户端服务器应用程序中返回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,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",strerror(errno));
    }
    else
    {
        fprintf(stderr,"%s-%d: Server not yet available...%s",strerror(errno));
        close(socketFD);
        socketFD = 0;
    }
}

return socketFD;
}

FYI
操作系统:Linux
Arch:ARM32
内核:2.6.26

解决方法

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

返回0表示socket()成功并为您提供文件描述符0.我怀疑您关闭的文件描述符之一具有文件描述符0,一旦关闭,下一次调用分配文件描述符的函数将返回fd 0因为它可用.

相关文章

linux常用进程通信方式包括管道(pipe)、有名管道(FIFO)、...
Linux性能观测工具按类别可分为系统级别和进程级别,系统级别...
本文详细介绍了curl命令基础和高级用法,包括跳过https的证书...
本文包含作者工作中常用到的一些命令,用于诊断网络、磁盘占满...
linux的平均负载表示运行态和就绪态及不可中断状态(正在io)的...
CPU上下文频繁切换会导致系统性能下降,切换分为进程切换、线...