Linux下端口複用(SO_REUSEADDR與SO_REUSEPORT)(轉載)

http://blog.chinaunix.net/uid-7390305-id-2057201.html php


做者:迷失千夏——拾露賞雲

解決性參考:Currently, Linux does not allow reuse of same local port for both TCP server and TCP client.並且小測試程序可以成功,和個人庫測試程序的差異也就在這一點了,所以接受鏈接和發起鏈接的端口分開便可。

其餘資料:

這個是搗亂最大的:http://www.ajaxstu.com/Linuxbiancheng/294968.html 請問:linux難道沒有端口重用嗎?我用SO_REUSEPORT報找不到

已經搞定,須要改/usr/include/asm/socket.h:/* To add :#define SO_REUSEPORT 15 */

http://hi.baidu.com/qiaoyong/blo ... b1f4190ff47707.html

freebsd與linux下bind系統調用小結

只考慮AF_INET的狀況(同一端口指ip地址與端口號都相同)
1.freebsd支持SO_REUSEPORT和SO_REUSEADDR選項,而linux只支持SO_REUSEADDR選項。
2.freebsd下,使用SO_REUSEPORT選項,兩個tcp的socket能夠綁定同一個端口;一樣,使用SO_REUSEPORT選項,兩個udp的socket能夠綁定同一個端口。
3.linux下,兩個tcp的socket不能綁定同一個端口;而若是使用SO_REUSEADDR選項,兩個udp的socket能夠綁定同一個端口。
4.freebsd下,兩個tcp的socket綁定同一端口,只有第一個socket得到數據。
5.freebsd下,兩個udp的socket綁定同一端口,若是數據包的目的地址是單播地址,則只有第一個socket得到數據,而若是數據包的目的地址是多播地址,則兩個socket同時得到相同的數據。
6.linux下,兩個udp的socket綁定同一端口,若是數據包的目的地址是單播地址,則只有最後一個socket得到數據,而若是數據包的目的地址是多播地址,則兩個socket同時得到相同的數據。

http://cache.baidu.com/c?m=9d78d ... er=baidu&fast=y
Unix網絡API

SO_REUSEADDR和SO_REUSEPORT
SO_REUSEADDR提供以下四個功能:
SO_REUSEADDR容許啓動一個監聽服務器並捆綁其衆所周知端口,即便之前創建的將此端口用作他們的本地端口的鏈接仍存在。這一般是重啓監聽服務器時出現,若不設置此選項,則bind時將出錯。 
SO_REUSEADDR容許在同一端口上啓動同一服務器的多個實例,只要每一個實例捆綁一個不一樣的本地IP地址便可。對於TCP,咱們根本不可能啓動捆綁相同IP地址和相同端口號的多個服務器。 
SO_REUSEADDR容許單個進程捆綁同一端口到多個套接口上,只要每一個捆綁指定不一樣的本地IP地址便可。這通常不用於TCP服務器。 
SO_REUSEADDR容許徹底重複的捆綁:當一個IP地址和端口綁定到某個套接口上時,還容許此IP地址和端口捆綁到另外一個套接口上。通常來講,這個特性僅在支持多播的系統上纔有,並且只對UDP套接口而言(TCP不支持多播)。 
SO_REUSEPORT選項有以下語義:
此選項容許徹底重複捆綁,但僅在想捆綁相同IP地址和端口的套接口都指定了此套接口選項才性。 
若是被捆綁的IP地址是一個多播地址,則SO_REUSEADDR和SO_REUSEPORT等效。 
使用這兩個套接口選項的建議
在全部TCP服務器中,在調用bind以前設置SO_REUSEADDR套接口選項; 
當編寫一個同一時刻在同一主機上可運行屢次的多播應用程序時,設置SO_REUSEADDR選項,並將本組的多播地址做爲本地IP地址捆綁。

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.
html

相關文章
相關標籤/搜索