1. 程式人生 > >Linux下埠複用(SO_REUSEADDR與SO_REUSEPORT)

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 ([email protected]):

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 ([email protected]):

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.

相關推薦

Linux(SO_REUSEADDRSO_REUSEPORT)

 freebsd與linux下bind系統呼叫小結:    只考慮AF_INET的情況(同一埠指ip地址與埠號都相同)freebsd支援SO_REUSEPORT和SO_REUSEADDR選項,而linux只支援SO_REUSEADDR選項。freebsd下,使用SO_REUS

linux 的問題

解決性參考:Currently, Linux does not allow reuse of same local port for both TCP server and TCP client.而且小測試程式能夠成功,和我的庫測試程式的差別也就在這一點了,因此接受連線和

SO_REUSEADDR

版權宣告:本部落格文章,大多是本人整理編寫,或在網路中收集,轉載請註明出處!    https://blog.csdn.net/tennysonsky/article/details/44062173 在《繫結( bind )埠需要注意的問題》提到:一個網路應用程式只能

套接字:SO_REUSEADDR

下面建立的套接字都是tcp套接字1.程序建立監聽套接字socket1,邦定一個指定埠,並接受了若干連線。那麼程序建立另外一個套介面socket2,並試圖邦定同一個埠時候,bind錯誤返回“Address already in use”(即使使用了SO_REUSEADDR).2

技術實現程式碼

在WINDOWS的SOCKET伺服器應用的程式設計中,如下的語句或許比比都是:    s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);   saddr.sin_family = AF_INET;   saddr.sin_addr.s_addr = htonl(INA

linux網路程式設計之TCP狀態轉換及

(1)TCP狀態轉換圖               其中圖中分為三種狀態:實線代表的主動發起連線,虛線代表的被動發起連線,細實線代表的可以雙向發起連線的狀態。 主動發起連線方狀態變化:1)主動發起連線的一方傳送SYN標誌位,進入SYN_SENT狀態,等待接收被髮起連線方

Linux網路程式設計》: (多個套接字繫結同一個

在《繫結( bind )埠需要注意的問題》提到:一個網路應用程式只能繫結一個埠( 一個套接字只能繫結一個埠 )。 請檢視《Linux網路程式設計》: 繫結( bind )埠需要注意的問題 實際上,預設的情況下,如果一個網路應用程式的一個套接字 綁定了一個埠( 佔用了 80

STM32之重對映簡單說明

(轉載摘取) 重對映步驟為: 1.開啟重對映時鐘和USART重對映後的I/O口引腳時鐘,            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB| RCC_APB2Periph_AFIO,ENABLE); 2.I/O口重

Linux網路程式設計——(多個套接字繫結同一個

實際上,預設的情況下,如果一個網路應用程式的一個套接字 綁定了一個埠( 佔用了 8000 ),這時候,別的套接字就無法使用這個埠( 8000 ), 驗證例子如下: #include <stdio.h> #include <stdlib.h> #

stm32學習筆記 F1系列重對映

(1)埠複用 STM32有很多的內建外設,這些外設的外部引腳都是與GPIO複用的。也就是說,一個GPIO如果可以複用為內建外設的功能引腳,那麼當這個GPIO作為內建外設使用的時候,叫做複用。 埠複用配置過程: 1>GPIO埠時鐘使能。 RCC_APB2PeriphCl

linux一個tomcat不同釋出多個專案

一、修改tomcat的conf目錄下的server.xml 配置service 節點,有幾個專案就相應的配置幾個service 節點; 注意修改Service name; Connector port; Engine name; Host appBase <?xm

linuxoracle11g R2的啟動關閉監聽、數據庫

source app var copy time lac started success let 一、啟動監聽與數據庫 1、啟動監聽: [html] view plain copy [[email protected]/* */ oracle]# s

Linux查看戶列表

情況 linux用戶 賬戶 hal shu 查看用戶列表 you 用戶組 不知道 原文地址:http://xiaod.in/read.php?77俺的centos vps上面不知道添加了多少個賬戶,今天想清理一下,但是以前還未查看過linux用戶列表,google了一下:一

linuxiptables命令的應用詳解

iptables 一、iptables的規則表和鏈。 表(tables)提供特定的功能,iptables內置了4個表,即filter表、nat表、mangle表和raw表,分別用於實現包過濾,網絡地址轉換、包重構(修改)和數據跟蹤處理。 鏈(chains)是數據包傳播的路徑,每一條鏈其實就是眾多規則中的

Linux文件系統---內核的交互接口

gbm 程序 系統環境 組成 linu 數據塊 ssd 其他 int 從磁盤到數據,從數據到文件,從文件到目錄,從目錄到文件系統,從文件系統到操作系統。構成了計算機中的IO讀寫機制。 整個磁盤可以分為1個MBR(Master Boot Record)和

Linux的硬鏈接軟鏈接

pan 如果 標識 ima 其中 new -i works jpg 本文總結自: https://www.ibm.com/developerworks/cn/linux/l-cn-hardandsymb-links/index.html#fig2 一個文件可以用下圖表示:

Linux軟件的安裝管理

linux軟件安裝方式一、源碼安裝方式: 1.下載、解壓源碼包通常源碼包的格式:".tar.gz"、".tar.bz2"2.分析安裝平臺環境./configure 後面可以加上軟件的安裝路勁以及所需模塊選項3.編譯、安裝軟件在執行./configure通過後,會在當

linux非root戶安裝軟件

出現問題 減少 操作 開始 RM -c str AD 難題 轉自:tlanyan 從windows轉移到Linux的用戶最開始有各種不適,因使用習慣水土不服而放棄Linux的不在少數。還沒有領略到Linux的美好就退卻,對於這類人只能說可惜。還有部分人在個人電腦上用Linu

linux的Mysql編譯安裝基本使用

load 虛擬機 sysctl 操作 依賴 down png 技術分享 徹底 一、大致操作步驟   環境介紹: OS:center OS6.5   mysql:5.6版本    1.關閉防火墻     查看防火墻狀態:service iptables stat

linux的IO重定向管道相關的知識簡析

io操作 簡單的 先來 兩個 整數 指令 cpu director 文件描述 一、bash重定向部分簡單翻譯 1.1、bash手冊關於重定向短短的註解(因為過於經典,所以摘錄出來) 我的翻譯要開始毀經典啦... 參考:https://blog.csdn.net/spch2