Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对于UDP套接字,当close()返回时,ip地址是否未绑定?_C_Sockets_Binding_Port_Bind - Fatal编程技术网

对于UDP套接字,当close()返回时,ip地址是否未绑定?

对于UDP套接字,当close()返回时,ip地址是否未绑定?,c,sockets,binding,port,bind,C,Sockets,Binding,Port,Bind,在阅读过程中,我了解到TCP套接字可以有一种称为TIME\u WAIT的状态。由于该状态,即使close(int-fd)函数返回0,TCP套接字也可能没有释放其绑定到的地址 考虑到UDP是无连接的,并且它不需要像TCP那样提供数据的可靠性要求,可以安全地假设一旦close(int fd)返回0,地址就被解除绑定了吗?是的,根据源代码,UDP\u destroy\u sock()(~line 2028)刷新任何挂起的帧,并释放释放地址的套接字 你可以用一个简单的例子来说明这一点。您需要netcat

在阅读过程中,我了解到TCP套接字可以有一种称为
TIME\u WAIT
的状态。由于该状态,即使
close(int-fd)
函数返回
0
,TCP套接字也可能没有释放其绑定到的地址


考虑到UDP是无连接的,并且它不需要像TCP那样提供数据的可靠性要求,可以安全地假设一旦
close(int fd)
返回
0
,地址就被解除绑定了吗?

是的,根据源代码,
UDP\u destroy\u sock()
(~line 2028)刷新任何挂起的帧,并释放释放地址的套接字

你可以用一个简单的例子来说明这一点。您需要
netcat
、一个客户端和一个服务器。在服务器上运行以下代码:

#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
int main() {
    struct sockaddr_in me;
    int sock;

    if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
        perror("socket error:");
        return -1;
        }
    memset(&me, 0, sizeof(me));
    me.sin_family = AF_INET;
    me.sin_port = htons(60000);
    me.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(sock, (struct sockaddr*)&me, sizeof(me)) == -1) {
        perror("bind error: ");
        return -1;
        }

    printf("On client execute:\n");
    printf("      nc -u {servers ip address} 60000\n\n");
    printf("type: hello world<enter>\n");
    printf("Hit enter when you've done this...");
    getchar();

    printf("\nNow check the input queue on this server\n");
    printf("    netstat -an|grep 60000\n");
    printf("Notice that we have buffered data we have not read\n");
    printf("(probably about 360 bytes)\n");
    printf("Hit enter to continue...");
    getchar();

    printf("\nI'm going to end. After I do, run netstat -an again\n");
    printf("and you'll notice port 60000 is gone.\n\n");
    printf("Re-run this program on server again and see you\n");
    printf("have no problem re-acquiring the UDP port.\n");
    return 0;
    }
#包括
#包括
#包括
#包括
#包括
#包括
int main(){
结构sockaddr_在我;
int袜子;
if((sock=socket(AF_INET,sock_DGRAM,IPPROTO_UDP))=-1){
perror(“套接字错误:”);
返回-1;
}
memset(&me,0,sizeof(me));
me.sin_family=AF_INET;
me.sin_port=htons(60000);
me.sin_addr.s_addr=htonl(在任何情况下);
if(bind(sock,(struct sockaddr*)&me,sizeof(me))=-1){
perror(“绑定错误:”);
返回-1;
}
printf(“在客户端执行:\n”);
printf(“nc-u{servers ip address}60000\n\n”);
printf(“类型:hello world\n”);
printf(“完成此操作后按回车键…”);
getchar();
printf(“\n现在检查此服务器上的输入队列\n”);
printf(“netstat-an | grep 60000\n”);
printf(“请注意,我们已经缓冲了尚未读取的数据\n”);
printf(“(大约360字节)\n”);
printf(“按回车键继续…”);
getchar();
printf(“\n我将结束。结束后,再次运行netstat-an\n”);
printf(“您会注意到端口60000已消失。\n\n”);
printf(“再次在服务器上运行此程序,然后再见”);
printf(“重新获取UDP端口没有问题。\n”);
返回0;
}

TL;DR:UDP套接字将立即关闭并解除绑定(除非它是与其他侦听器的广播/多播地址)

时间等待由原始指定,仅适用于TCP。在关闭TCP中的套接字之前,它需要最长2*的段生存期

史蒂文斯的名著还为好奇者更详细地解释了TCP的时间等待

UDP没有连接等待时间不是该协议的一部分。

Linux源代码虽然与基于Linux的系统上的潜在专有行为相关,但不是此类问题的权威

最初的1981年DARPA TCP是权威的,其基础定义了套接字API的预期行为


同样相关的还有早期internet中的TCP/IP,它支持Windows、iOS和OSX,并提供了TCP/IP RFC的权威参考实现。BSD堆栈仍然被视为(Facebook在2014年年中发布了一个专家角色,以帮助Linux达到或超过FreeBSD堆栈的可靠性和性能)。

能否添加一个代码示例(可以运行)如何显示TCP不会释放套接字上的地址而UDP会关闭的场景?我认为不需要展示TCP套接字的TIME_WAIT状态,因为这是规范强制要求的状态,它几乎到处都有文档记录,Linux内核包含影响其持续时间的可调参数。套接字在正常终止时总是进入TIME_WAIT状态。我认为OP试图确认收单机构进程结束时UDP端口已完全释放。我同意linux内核参考是权威性的答案,但他希望有多一点信心这是真的——一种测试方法。