这对你来说可能看起来很基础,但由于这是我第一次使用 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/