解释在活动套接字(而不是被动套接字)上调用时接受函数的行为

时间:2013-09-11 13:41:15

标签: c network-programming

我有一本教科书TCP服务器。其中我在活动套接字上使用accept函数。注意:我已经注释掉了在listen中监听listenfd的调用。

#include <stdlib.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>

void do_work(int sockfd, int lisfd)
{
    printf("Child's process id is %d\n", getpid());
    close(lisfd);
    const int MAXLINE = 30;
    char buff[MAXLINE];
    time_t ticks;
    ticks = time(NULL);
    snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
    write(sockfd, buff, strlen(buff));
    close(sockfd);
    exit(0);
}

//argc and argv include the program name itself too in the count and array 
int main(int argc, char** argv[])
{
    int listenfd, connfd;
    const int IPLEN = 50;
    //max number of connections that server can handle simultaneously
    const int LISTENQ = 10;
    struct sockaddr_in servaddr,cliaddr;
    char cliip[IPLEN];
    socklen_t len;
    const int PORT = 8088;

    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0) ) < 0)
    {
        printf("listenning socket error %s\n", strerror(errno));
        exit(-1);
    }

    //initialize sockaddr stuctures to zero
    bzero(&cliaddr, sizeof(cliaddr));
    bzero(&servaddr, sizeof(servaddr));
    //initialize value-result argument to accept
    len = sizeof(cliaddr);

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    // INADDR_ANY means that socket bound to this servaddr can accept connection
    // from any of the interface available on the system
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
    {
        printf("bind error %s\n", strerror(errno));
        exit(-1);
    }

    //listen(listenfd, LISTENQ);

    printf("Parent's process id is %d\n", getpid());

    for (int i = 0; i < 2; i++)
    //for(;;)
    {
        connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len);
        printf("accepting connection from ip %s on port %lu\n",
                inet_ntop(AF_INET, &cliaddr.sin_addr, &cliip, sizeof(cliip)), ntohl(cliaddr.sin_port));
        pid_t childpid;
        if ((childpid = fork()) == 0)
        {
            do_work(connfd,listenfd);
        }
        // if you don't close it here, then connfd shall remain open in parent process and EOF shall not be issued as FIN segment shall not be sent by tcp
        close(connfd); 
    }
}

现在,当我通过一个简单的客户端连接它时,它会给我一个这样的输出。

Parent's process id is 11145
accepting connection from ip 0.0.0.0 on port 0
accepting connection from ip 0.0.0.0 on port 0
Child's process id is 11146
Child's process id is 11147

我想了解的是:0.0.0.0在这里意味着什么? (Google表示这意味着这里没有tcp / ip连接。)但我无法将其置于透视之中。有什么帮助吗?

1 个答案:

答案 0 :(得分:3)

最可能的是对accept()的调用失败了。

在调查accept()之前,您应测试-1是否返回cliaddr


此外,您显示的代码close()是第一个do_Work()后的列表套接字(位于accept()中)。以下任何accept()肯定会失败。 我错过了对fork()的呼吁


根据 Duck 的评论:

但是,只要listen()的注释被注释掉accept(),就必须失败。