socket() 在 C 客户端服务器应用程序中返回 0 [英] socket() returns 0 in C client server application

查看:17
本文介绍了socket() 在 C 客户端服务器应用程序中返回 0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个包含多个服务器套接字的应用程序,每个套接字都在一个唯一的线程中运行.
其中一个线程调用外部实用程序(脚本).此脚本调用实用程序(客户端),该实用程序将消息发送到服务器套接字之一.

I'm working on an application that contains several server sockets that each run in a unique thread.
An external utility (script) is called by one of the threads. This script calls a utility (client) that sends a message to one of the server sockets.

最初,我使用 system() 来执行这个外部脚本,但我们不能使用它,因为我们必须确保服务器套接字在被分叉执行的子进程中关闭外部脚本.
我现在自己调用 fork()execvp() .我 fork() 然后在子进程中关闭所有服务器套接字,然后调用 execvp() 来执行脚本.

Initially, I was using system() to execute this external script, but we couldn't use that because we had to make sure the server sockets were closed in the child that was forked to execute the external script.
I now call fork() and execvp() myself. I fork() and then in the child I close all the server sockets and then call execvp() to execute the script.

现在,所有这些都运行良好.问题是有时脚本会向服务器应用程序报告错误.该脚本通过调用另一个应用程序(客户端)来发送这些错误,该应用程序打开一个 TCP 套接字并发送适当的数据.我的问题是客户端应用程序获取 socket() 系统调用返回的 0 值.

Now, all of that works fine. The problem is that at times the script reports errors to the server app. The script sends these errors by calling another application (client) which opens a TCP socket and sends the appropriate data. My issue is that the client app gets a value of 0 returned by the socket() system call.

注意:这仅在使用我的 forkExec() 函数调用脚本/客户端应用程序时发生.如果手动调用脚本/客户端应用程序,socket() 调用会正确执行并且一切正常.

NOTE: This ONLY occurs when the script/client app is called using my forkExec() function. If the script/client app is called manually the socket() call performs appropriately and things work fine.

根据这些信息,我怀疑它在我下面的 fork() execvp() 代码中......有任何想法吗?

Based on that information I suspect it's something in my fork() execvp() code below... Any ideas?

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;
}

仅供参考
操作系统:Linux
架构:ARM32
内核:2.6.26

FYI
OS: Linux
Arch: ARM32
Kernel: 2.6.26

推荐答案

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

socket() returns -1 on error.

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

A return of 0 means socket() succeeded and gave you file descriptor 0. I suspect that one of the file descriptors that you close has file descriptor 0 and once it's closed the next call to a function that allocated a file descriptor will return fd 0 as it's available.

这篇关于socket() 在 C 客户端服务器应用程序中返回 0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆