1. 程式人生 > >linux下 埠複用的問題

linux下 埠複用的問題

解決性參考: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 ([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.