c - 程序如何在通过 listen() 后等待传入连接

标签 c sockets

我正在学习 c 语言的套接字编程,并试图理解 listen() 在代码中到底做了什么。我知道它定义了可以排队等待 accept() 的最大连接数,但除此之外我似乎无法理解它在做什么。

根据我学习的课文,

listen() waits for incoming connections. Accept() gets the pending connection on the port you are listen()ing.

查看执行流程,我看到 listen() 实际上只被调用一次,之后只有 accept() 处理传入的任何新连接。那么,如何如果一旦我们进入接受循环就永远不会调用 listen(),服务器会监听 future 的请求吗?

                       +----------+
                       |socket()  |
                       +----------+

                       +----------+
                       |bind()    |
                       +----------+

                       +----------+
                       |listen()  |
                       +----------+
                       +----------+
                       |while(1)  |
                       |----------|
                       |accept()  |
                       |          |
                       |          |
                       +----------+

这是我正在处理的代码:

/*Server*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

int main()
{
    int sockfd, newsock;
    char buffer[200];
    memset(buffer, 0, sizeof(buffer));

    /*Creating a new socket*/
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("Socket error");
        exit(1);
    }

    /*Creating socket address structure*/
    struct sockaddr_in server_addr, client_address;

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(7200);
    server_addr.sin_addr.s_addr = inet_addr("192.168.1.2");
    bzero(&(server_addr.sin_zero),8);

    /*Binding*/
    if(bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        perror("Bind error");
        exit(1);
    }

    /*Listening for new connection; maximum 5*/
    if(listen(sockfd, 5) < 0)
    {
        perror("Listen error");
    }


    while(1)
    {
        socklen_t len = sizeof(client_address);

        if((newsock = accept(sockfd, (struct sockaddr *)&client_address, &len)) < 0)
        {
            perror("Accept error");
            exit(1);
        }

        int i;
        if((i = read(newsock, buffer, sizeof(buffer))) < 0)
        {
            perror("Receive error");
            exit(1);
        }
        if(i == 0)
        {
            printf("Socket closed remotely\n");
        }
        if(i > 0)
        {
            printf("received %d bytes\n",i);
            printf("data: %s",buffer);
        }

        close(newsock);
    }
    close(sockfd);

    return 0;
}

最佳答案

listen() waits for incoming connections.

这只是一种误导性的简化。此系统调用将套接字标记为监听。这意味着它通知操作系统嘿,注意这个套接字,您将在上面接收连接请求

真正的等待函数是accept 函数等待传入连接。每次调用它时(在阻塞上下文中),都会发生以下两种情况之一:

  • 如果有未接受的连接(由第二个 listen 参数控制)accept 只获取一个连接就完成了
  • 否则它实际上会等待连接可用再返回

关于c - 程序如何在通过 listen() 后等待传入连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9993770/

相关文章:

sockets - 什么时候需要 TCP 选项 SO_LINGER (0)?

c# - 异步TCP套接字的怪异行为

c - 在初始化互斥量时在简单的生产者消费者示例中出错

c - 从 strtok 向其传递字符串数组后,execvp 返回错误 "No such file or directory"

java - 当数据不以新行结尾时,有没有办法从套接字中读取数据?

sockets - 如何在 Go 中停止监听服务器

java - java中的Python套接字

c - 从结构初始化为动态分配的 char 数组

c++ - OpenGL 中的文本使用 SDL_TTF

c - 使用函数通过 strcmp 对 argv 值进行排序