Linux下端口复用(SO_REUSEADDR与SO_REUSEPORT)
freebsd与linux下bind系统调用小结:
只考虑AF_INET的情况(同一端口指ip地址与端口号都相同)
- freebsd支持SO_REUSEPORT和SO_REUSEADDR选项,而linux只支持SO_REUSEADDR选项。
- freebsd下,使用SO_REUSEPORT选项,两个tcp的socket可以绑定同一个端口;同样,使用SO_REUSEPORT选项,两个udp的socket可以绑定同一个端口。
- linux下,两个tcp的socket不能绑定同一个端口;而如果使用SO_REUSEADDR选项,两个udp的socket可以绑定同一个端口。
- freebsd下,两个tcp的socket绑定同一端口,只有第一个socket获得数据。
- freebsd下,两个udp的socket绑定同一端口,如果数据包的目的地址是单播地址,则只有第一个socket获得数据,而如果数据包的目的地址是多播地址,则两个socket同时获得相同的数据。
- linux下,两个udp的socket绑定同一端口,如果数据包的目的地址是单播地址,则只有最后一个socket获得数据,而如果数据包的目的地址是多播地址,则两个socket同时获得相同的数据。
Unix网络API
SO_REUSEADDR和SO_REUSEPORT
SO_REUSEADDR提供如下四个功能:
- SO_REUSEADDR允许启动一个监听服务器并捆绑其众所周知端口,即使以前建立的将此端口用做他们的本地端口的连接仍存在。这通常是重启监听服务器时出现,若不设置此选项,则bind时将出错。
- SO_REUSEADDR允许在同一端口上启动同一服务器的多个实例(多个进程),只要每个实例捆绑一个不同的本地IP地址即可。在有多块网卡或者用IP Alias技术的机器可以测试这种情况。 对于TCP,我们根本不可能启动捆绑相同IP地址和相同端口号的多个服务器。
- SO_REUSEADDR允许单个进程捆绑同一端口到多个套接口上,只要每个捆绑指定不同的本地IP地址即可。这一般不用于TCP服务器。
- SO_REUSEADDR允许完全重复的捆绑:当一个IP地址和端口绑定到某个套接口上时,还允许此IP地址和端口捆绑到另一个套接口上。一般来说,这个特性仅在支持多播的系统上才有,而且只对UDP套接口而言,不用于TCP(TCP不支持多播)。
SO_REUSEPORT选项有如下语义:
- 此选项允许完全重复捆绑,但仅在想捆绑相同IP地址和端口的套接口都指定了此套接口选项才行。 如果被捆绑的IP地址是一个多播地址,则SO_REUSEADDR和SO_REUSEPORT等效。
使用这两个套接口选项的建议:
- 在所有TCP服务器中,在调用bind之前设置SO_REUSEADDR套接口选项。
- 当编写一个同一时刻在同一主机上可运行多次的多播应用程序时,设置SO_REUSEADDR选项,并将本组的多播地址作为本地IP地址捆绑。
附
Q:编写 TCP/SOCK_STREAM 服务程序时,SO_REUSEADDR到底什么意思?
A:这个套接字选项通知内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用端口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息,指明"地址已经使用中"。如果你的服务程序停止后想立即重启,而新套接字依旧使用同一端口,此时SO_REUSEADDR 选项非常有用。必须意识到,此时任何非期望数据到达,都可能导致服务程序反应混乱,不过这只是一种可能,事实上很不可能。
一个套接字由相关五元组构成,协议、本地地址、本地端口、远程地址、远程端口。SO_REUSEADDR 仅仅表示可以重用本地本地地址、本地端口,整个相关五元组还是唯一确定的。所以,重启后的服务程序有可能收到非期望数据。必须慎重使用 SO_REUSEADDR 选项。
if( getsockopt( sockfd , SOL_SOCKET, SO_REUSEPORT,
( char *)&optval, &optlen ) < 0 )
printf( " get socket error /n" ); if( setsockopt( sockfd , SOL_SOCKET, SO_REUSEPORT,
( char *)&optval, sizeof( optval ) ) < 0 )
printf( " set socket error /n" ); 编译报错:
libtcp.c:1195: error: `SO_REUSEPORT' undeclared (first use in this function)
libtcp.c:1195: error: (Each undeclared identifier is reported only once
libtcp.c:1195: error: for each function it appears in.)
需要改
/usr/include/asm/socket.h:/* To add :#define SO_REUSEPORT 15 */
What is the difference between SO_REUSEADDR and SO_REUSEPORT?
from:UNIX Socket FAQ
SO_REUSEADDR allows your server to bind to an address which is in a TIME_WAIT state. It does not allow more than one server to bind to the same address. It was mentioned that use of this flag can create a security risk because another server can bind to a the same port, by binding to a specific address as opposed to INADDR_ANY. The SO_REUSEPORT flag allows multiple processes to bind to the same address provided all of them use the SO_REUSEPORT option.
From Richard Stevens (rstevens@noao.edu):
This is a newer flag that appeared in the 4.4BSD multicasting code (although that code was from elsewhere, so I am not sure just who invented the new SO_REUSEPORT flag).
What this flag lets you do is rebind a port that is already in use, but only if all users of the port specify the flag. I believe the intent is for multicasting apps, since if you're running the same app on a host, all need to bind the same port. But the flag may have other uses. For example the following is from a post in February:
From Stu Friedberg (stuartf@sequent.com):
SO_REUSEPORT is also useful for eliminating the try-10-times-to-bind hack in ftpd's data connection setup routine. Without SO_REUSEPORT, only one ftpd thread can bind to TCP (lhost, lport, INADDR_ANY, 0) in preparation for connecting back to the client. Under conditions of heavy load, there are more threads colliding here than the try-10-times hack can accomodate. With SO_REUSEPORT, things work nicely and the hack becomes unnecessary.
I have also heard that DEC OSF supports the flag. Also note that under 4.4BSD, if you are binding a multicast address, then SO_REUSEADDR is condisered the same as SO_REUSEPORT (p. 731 of "TCP/IP Illustrated, Volume 2"). I think under Solaris you just replace SO_REUSEPORT with SO_REUSEADDR.
From a later Stevens posting, with minor editing:
Basically SO_REUSEPORT is a BSD'ism that arose when multicasting was added, even thought it was not used in the original Steve Deering code. I believe some BSD-derived systems may also include it (OSF, now Digital Unix, perhaps?). SO_REUSEPORT lets you bind the same address *and* port, but only if all the binders have specified it. But when binding a multicast address (its main use), SO_REUSEADDR is considered identical to SO_REUSEPORT (p. 731, "TCP/IP Illustrated, Volume 2"). So for portability of multicasting applications I always use SO_REUSEADDR.
from: http://www.cnblogs.com/mydomain/archive/2011/08/23/2150567.html
Linux下端口复用(SO_REUSEADDR与SO_REUSEPORT)的更多相关文章
- Linux下端口被占用,关掉端口占用的方法
Linux下端口被占用(例如端口3000),关掉端口占用的进程的方法: 1.netstat -tln | grep 3000 2.sudo lsof -i:3000 3.sudo kill -9 进程
- TCP套接字端口复用SO_REUSEADDR
下面建立的套接字都是tcp套接字 1.进程创建监听套接字socket1,邦定一个指定端口,并接受了若干连接.那么进程创建另外一个套接口socket2,并试图邦定同一个端口时候,bind错误返回“Add ...
- 一文打尽 Linux/Windows端口复用实战
出品|MS08067实验室(www.ms08067.com) 本文作者:Spark(Ms08067内网安全小组成员) 定义:端口复用是指不同的应用程序使用相同端口进行通讯. 场景:内网渗透中,搭建隧道 ...
- Linux下端口映射工具rinetd
Linux下简单好用的工具rinetd,实现端口映射/转发/重定向官网地址http://www.boutell.com/rinetd 软件下载wget http://www.boutell.com/r ...
- 查看Linux下端口占用情况的命令
在使用Linux系统的过程中,有时候会遇到端口被占用而导致服务无法启动的情况.比如HTTP使用80端口,但当启动Apache时,却发现此端口正在使用. 这种情况大多数是由于软件冲突.或者默认端口设置不 ...
- linux 下端口close_wait 过多问题
情景描述:系统产生大量“Too many open files” 原因分析:在服务器与客户端通信过程中,因服务器发生了socket未关导致的closed_wait发生,致使监听port打开的句柄数到了 ...
- 查看windows和linux下端口是否被占用
1.windows cmd输入netstat -ano |findstr "端口号" 查看到1202端口被使用的进程PID是10692 输入tasklist |findstr 10 ...
- Linux下端口被占用解决
有时候关闭软件后,后台进程死掉,导致端口被占用.下面以JBoss端口8083被占用为例,列出详细解决过程. 解决方法: 1.查找被占用的端口 netstat -tln netstat -tln | ...
- [linux]查看linux下端口占用
netstat netstat -an | grep 23 (查看是否打开23端口) 查看端口占用情况的命令:lsof -i [root@www ~]# lsof -i COMMAND PID USE ...
随机推荐
- IOS开发---视频录制
今天研究了一下使用app录制视频的功能,感觉还是挺简单的.使用了AVFoundation框架,代码比较死,按步骤调用就行. 分享一下今天做的Demo的步骤 一,初始化输入设备,这里涉及到前,后摄像头: ...
- github学习(三)
Git学习(二) 分支学习: 创建新分支dev:git branch dev 切换到dev分支:git checkout dev 可以简写为一句话:git checkout -b dev 可以用命令g ...
- Windows 2012服务器安装GPU版TensorFlow完全攻略
一.首先,推荐用Anaconda安装 因为Anaconda本身就已经默认安装了很多常用的Python库,可以省去大量的库安装过程,并且解决兼容性问题. Anaconda本身的安装也非常简单,搜索Ana ...
- [FJOI2007]轮状病毒
题目描述 轮状病毒有很多变种.许多轮状病毒都是由一个轮状基产生.一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成.2个原子之间的边表示这2个原子之间的信息通道,如图1. n轮状病毒的产生规律 ...
- [ZJOI2009]染色游戏
Description 一共n × m 个硬币,摆成n × m 的长方形.dongdong 和xixi 玩一个游戏, 每次可以选择一个连通块,并把其中的硬币全部翻转,但是需要满足存在一个 硬币属于这个 ...
- 【NOIP2015TG】solution
链接:https://www.luogu.org/problem/lists?name=&orderitem=pid&tag=83%2C32 D1T1(magic) 题意:看题目.. ...
- [BZOJ]1095 Hide捉迷藏(ZJOI2007)
一道神题,两种神做法. Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特 ...
- 一个小小的抽奖活动测试脚本(python2.7)
# coding=utf-8import requestsimport cx_Oracletns=cx_Oracle.makedsn('172.30.0.155',1521,'szdev')db1=c ...
- Delphi7通过SendMessage来实现默认打印机的切换
具体代码 procedure SetDefaultPrinter(NewDefPrinter: string); var ResStr: array[0..255] of Char; begin St ...
- 分布式改造剧集之Redis缓存采坑记
Redis缓存采坑记 前言 这个其实应该属于分布式改造剧集中的一集(第一集见前面博客:http://www.cnblogs.com/Kidezyq/p/8748961.html),本来按照顺序 ...