Socket中SO_REUSEADDR简介
SO_REUSEADDR:字面意思重复使用地址
一般来说,一个端口释放后会等待两分钟之后才能再次被使用,SO_REUSEADDR是让端口释放后立即就可以被再次使用。
SO_REUSEADDR用于对TCP套接字处于TIME_WAIT状态下的socket,才可以重复绑定使用。server程序总是应该在调用bind之前设置SO_REUSEADDR套接字选项。对于TCP,先调用close()的一方会进入TIME_WAIT状态
SO_REUSEADDR的功能:
SO_REUSEADDR允许启动一个监听服务器并捆绑其众所周知端口,即使以前建立的将此端口用作他们的本地端口的连接仍存在,这通常时重启监听服务器时出现,若不设置此选项,则bind时将出错。
SO_REUSEADDR允许在同一端口上启动同一服务器的多个实例,只要每个实例捆绑一个不同的本地IP地址即可。对于TCP,根本不可能启动捆绑相同IP地址和相同端口号的多个服务器。
SO_REUSEADDR允许单个进程捆绑同一端口到多个套接口上,只要每个捆绑指定不同的本地IP地址即可。这一般不用于TCP服务器
SO_REUSEADDR允许完全重复的捆绑,当一个IP地址和端口号绑定到某个套接口上时,还允许此IP地址和端口捆绑到另一个套接口上。一般来说,这个特性,仅在支持多播的系统上才有,而且只对UDP套接口而言(TCP不支持多播)。
使用SO_REUSEADDR的建议:
1. 在所有TCP服务器中,在调用bind之前设置SO_REUSEADDR套接口选项(不一定,一般在调试阶段)
2. 当编写一个同一时刻在同一主机上可运行多次的多播应用程序时,设置SO_REUSEADDR选项,并将本组的多播地址作为本地IP地址捆绑。
问题场景
当在开发一个socket服务器程序并反复调试的时候,可能会发现这样一种情况。每次kill掉该服务器进程并重新启动的时候,都会出现bind错误:error:98,Address already in use。然后再kill掉该进程,再次重新启动的时候,就bind成功了。
这实际上是TIME_WAIT在起作用!linux的TIME_WAIT大概是2分钟,在调试的时候需要等2分钟?
解决问题
一般是没有办法关闭掉TIME_WAIT,可以使用SO_REUSEADDR,允许端口在释放后被立即使用。
// 设置允许地址重用
int on = ;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
上面两行代码,在套接字listenfd设置允许地址重用(on = 1,如果on = 0就是不允许重用)。这样每次bind的时候,如果此端口正在使用的话,bind就会把端口"抢"过来,就不会报错了。
TIME_WAIT存在的理由:
(1)可靠的实现TCP全双工连接的终止
(2)允许老的重复分节在网络中消逝
解释如下:
(1)如果服务器最后发送的ACK因为某种原因丢失了,那么客户一定会重新发送FIN,这样因为有了TIME_WAIT的存在,服务器会重新发送ACK给客户,如果没有TIME_WAIT,那么无论客户有没有收到ACK,服务器都已经关掉连接了,此时客户重新发送FIN,服务器将不会发送ACK,而是RST,从而使客户端报错。也就是说,TIME_WAIT有助于可靠地实现TCP全双工连接的终止。
(2)如果没有TIME_WAIT,我们可以在最后一个ACK还未到客户的时候,就建立一个新的连接。那么此时,如果客户收到了这个ACK的话,会出现混乱,必须保证这个ACK完全消逝之后,才能建立新的连接。也就是说,TIME_WAIT允许老的重复分节在网络中消逝。
建议:在最终的服务器版本,还是不要设置为端口可复用。
Socket中SO_REUSEADDR简介的更多相关文章
- Socket中SO_REUSEADDR详解
1.一般来说,一个端口释放后会等待两分钟之后才能再被使用,SO_REUSEADDR是让端口释放后立即就可以被再次使用. SO_REUSEADDR用于对TCP套接字处于TIME_WAIT状态下的sock ...
- linux socket中的SO_REUSEADDR
Welcome to the wonderful world of portability... or rather the lack of it. Before we start analyzing ...
- Socket通信原理简介
Socket通信原理简介 字数1011 阅读1766 评论2 喜欢11 何谓socket 计算机,顾名思义即是用来做计算.因而也需要输入和输出,输入需要计算的条件,输出计算结果.这些输入输出可以抽象为 ...
- ZeroMQ接口函数之 :zmq_msg_recv - 从一个socket中接受一个消息帧
ZeroMQ 官方地址 :http://api.zeromq.org/4-2:zmq_msg_recv zmq_msg_recv(3) ØMQ Manual - ØMQ/3.2.5 Name zmq_ ...
- Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)
声明:该博文以socket中,关闭输出流为例进行说明. 为了方便讲解,我们把DataOutputstream dout = new DataOutputStream(new BufferedOutpu ...
- 2、 Spark Streaming方式从socket中获取数据进行简单单词统计
Spark 1.5.2 Spark Streaming 学习笔记和编程练习 Overview 概述 Spark Streaming is an extension of the core Spark ...
- Spring中AOP简介与切面编程的使用
Spring中AOP简介与使用 什么是AOP? Aspect Oriented Programming(AOP),多译作 "面向切面编程",也就是说,对一段程序,从侧面插入,进行操 ...
- Socket中常见的几个转换函数(htonl,htons,ntohl,ntohs,inet_addr,inet_ntoa)
Socket中常见的几个转换函数(htonl,htons,ntohl,ntohs,inet_addr,inet_ntoa) htonl() htons() ntohl() ntohs()及inet_n ...
- ioctl在socket中的一些用法及示例
原文: http://blog.chinaunix.net/uid-20692625-id-3172833.html ----------------------------------------- ...
随机推荐
- 萌新带你开车上p站(二)
本文作者:萌新 前情提要:萌新带你开车上p站(一) 0x04flag 看题目描述似乎是一个和脱壳相关的逆向题目 按照给出的地址先下载过来 file看看 是个可执行文件 执行之 emm什么都看不出来, ...
- PHP中debug基本方法
一.检查是否有语法错误 php -l test.php 二.基本调试基本调试 API: var_dump($var);print_r($var);echo $var; 基本的配置: display_e ...
- scp 使用方法
scp就是secure copy,一个在linux下用来进行远程拷贝文件的命令.有时我们需要获得远程服务器上的某个文件,该服务器既没有配置ftp服务器,也没有做共享,无法通过常规途径获得文件时,只需要 ...
- SpringMVC框架详细教程(六)_HelloWorld
HelloWorld 在src下创建包com.pudding.controller,然后创建一个类HelloWorldController: package com.pudding.controlle ...
- LIMS产品 - Labvantage技术版本
最新版本的Labvantage8使用Java版本为Java7(Java8使用最广泛,最新版本为Java12),中间件使用JBoss(国内小型信息化系统(LIMS.QMS等)java体系一般使用Tomc ...
- JUC强大的辅助类讲解--->>>CountDownLatchDemo (减少计数)
原理: CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,这些线程会阻塞.其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞), ...
- gdb 调试中No symbol “***” in current context解决方法
主要是因为GCC/G++版本和GDB不匹配造成的,网上也有说是因为O2优化问题,具体啥原因需要自己尝试一下. 解决: 放狗搜索,解决办法是在编译是加-gdwarf-3即可,出现这样的原因是gcc,gd ...
- [腾讯云]简单在腾讯云 CenTOS7.0 安装Nginx,Mysql(MariaDB),Memcache,解析PHP!
1.安装LNMP之前要安装EPEL,以便安装源以外的软件,如Nginx,phpMyAdmin等. yum install epel-release 2.安装Nginx a) yum install n ...
- TensorFlow keras卷积神经网络 添加L2正则化
model = keras.models.Sequential([ #卷积层1 keras.layers.Conv2D(32,kernel_size=5,strides=1,padding=" ...
- Docker 搭建 ELK 集群步骤
前言 本篇文章主要介绍在两台机器上使用 Docker 搭建 ELK. 正文 环境 CentOS 7.7 系统 Docker version 19.03.8 docker-compose version ...