c - C中的网络; bind() 需要它的论点吗?

标签 c linux sockets

这对你来说可能看起来很基础,但由于这是我第一次使用 C 语言进行网络体验,我想确保我没有做任何愚蠢的事情,所以我想......比遇到一些未定义的、奇怪的东西更安全沿途某处的行为。
考虑以下用于在 C 中设置服务器套接字的代码:

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


int main(int argc, char* argv[]) {

    int listenfd, connfd;
    struct sockaddr_in serv_addr;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    // setting 'serv_addr'
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serv_addr.sin_port = htons(5000);

    bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));

    if (listen(listenfd, 10) == -1) {
        printf("Failed to listen\n");
        return -1;
    }



    while(1) {
        connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL);

        // do some writing/reading with connfd...

        close(connfd);
    }

    return 0;
}

注意 bind() 函数将 &struct sockaddr_in 作为参数。
根据doc :

bind() assigns the address specified by addr to the socket referred to by the file descriptor sockfd.

现在假设在 while 循环的执行过程中,我没有对这个 serv_addr 进行任何显式引用。
struct sockaddr_in是socket需要的,还是bind()返回后,struct sockaddr_in不再需要了?
套接字是否以某种方式进行了任何隐式引用?

更准确地说,下面的代码安全吗?

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


int some_other_function() {

    int listenfd;
    /* struct sockaddr_in is defined locally in some_other_function()*/
    struct sockaddr_in serv_addr;


    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    // setting 'serv_addr'
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serv_addr.sin_port = htons(5000);

    bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));

    if (listen(listenfd, 10) == -1) {
        printf("Failed to listen\n");
        return -1;
    }

    return listenfd;
}   /* if the socket will refer to &serv_addr from now on, it'll dereference a dangling pointer */



int main(int argc, char* argv[]) {

    int listenfd=some_other_function();
    int connfd;

    while(1) {

        /** is sockaddr_in serv_addr being referenced here? is it needed by accept()? **/

        connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL);

        // do some writing/reading with connfd...

        close(connfd);
    }

    return 0;
}

最佳答案

不,它没有。 address参数的内容被内核​​复制;您可以在调用返回后立即重用或释放该内存。

事实上,这里可以做一个更一般的陈述:除非文档特别说明,否则通过指针引用传递给内核的参数只需要在系统调用期间保持“事件”状态。如果需要,它们的值将由内核复制。

关于c - C中的网络; bind() 需要它的论点吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29978076/

相关文章:

c - 问题添加从 fgetc 收到的值?

将文本文件中的单词大写

c - 哪里可以在线阅读C99官方语言标准手册/引用/规范?

linux - pip安装报错python3 linux

C++ HTTP Winsock : "Banned URL" at school, 即使是允许的网站

c - getaddrinfo() 函数返回错误的 IP 地址

c++ - 如何在没有库的情况下在 C++ 中初始化套接字

c - 自动变量和寄存器变量——优化一样吗?

linux - 我的 git 1.8.4.2-1 有什么问题?

c - 当两者都是 USB 驱动器时,如何在 c 中检查/dev/sda 下到底是什么以及/dev/sdb 下是什么