对于UDP套接字,当close()返回时,ip地址是否未绑定?
在阅读过程中,我了解到TCP套接字可以有一种称为对于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
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内核参考是权威性的答案,但他希望有多一点信心这是真的——一种测试方法。