http://blog.csdn.net/justlinux2010/article/details/11140383
http://wiki.treck.com/setsockopt
omping 命令
tcpdump
netstat
dropwatch
集群之間的探活用的是組播消息,出現這種問題肯定是因為接收組播報文出了問題。
之前遇到過一次是因為網關配置的不一致導致的。
"netstat -gn"命令來查看當前哪些網卡加入了哪些組播組【只針對消息的接收方,在消息的發送方是沒辦法netstat -gn出來的】
[root@shanghai-OA-pm-2K1code-10-1-22-246 ~]# netstat -gn
IPv6/IPv4 Group Memberships
Interface RefCnt Group
--------------- ------ ---------------------
lo 1 224.0.0.1 //lo具有組播能力
eth0 1 224.0.0.1 //eth0具有組播能力
eth1 1 238.2.2.2
eth1 1 238.1.2.138
eth1 1 238.1.2.107
eth1 1 238.1.2.106
eth1 1 238.1.2.104
eth1 1 238.1.2.101
eth1 1 224.0.0.1
netstat -gn 無法顯示對應的程序端口
netstat -anu 作為補充使用,通過端口可找到對應的程序
[root@shanghai-OA-pm-2K1code-10-1-22-246 ~]# netstat -anu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
udp 0 0 238.1.2.138:10138 0.0.0.0:*
udp 0 0 0.0.0.0:161 0.0.0.0:*
udp 0 0 0.0.0.0:53 0.0.0.0:*
udp 0 0 10.1.22.246:42814 10.221.75.116:1514 ESTABLISHED
udp 0 0 0.0.0.0:43740 0.0.0.0:*
udp 0 0 238.1.2.101:10101 0.0.0.0:*
udp 0 0 238.1.2.104:10104 0.0.0.0:*
udp 0 0 238.1.2.106:10106 0.0.0.0:*
udp 0 0 238.1.2.107:10107 0.0.0.0:*
In practice UDP sockets which are used to receive multicast traffic are usually bound to address 0.0.0.0. These can receive UDP packets for all unicast and multicast addresses。
http://2849159106.blog.51cto.com/7881853/1851224
組播地址
224.0.0.0到239.255.255.25
從224.0.0.0到239.255.255.255都是這樣的地址。224.0.0.1特指所有主機, 224.0.0.2特指所有路由器。這樣的地址多用於一些特定的程序以及多媒體程序。如果你的主機開啟了IRDP(Internet路由發現協議,使用組播功能)功能,那么你的主機路由表中應該有這樣一條路由。
224.0.0.5指OSPF路由器,地址多用於一些特定的程序以及多媒體程序
http://blog.sina.com.cn/s/blog_3d8529400100h2b9.html
多播組中的成員是與接口相關聯的,一個進程可以在多個接口上加入同一多播組。
一個初始TTL為0的多播數據報將被限制在同一主 機。在默認情況下,待傳多播數據報的TTL被設置為1,這將使多播數據報僅局限在同一子網內傳送。更大的TTL值能被多播路由器轉發。
從224.0.0.0到224.0.0.255的特殊地址空間是打算用於多播范圍不超過1跳的應用。不管TTL值是多少,多播路由器均不轉發目 的地址為這些地址中的任何一個地址的數據報。
IP地址224.0.0.1.該地址被稱為所有主機組地址。它涉及在一個物理網絡中的所有具備多播能力的主機和路由器。當接口初始化后,所有具備多播能力接口上的主機均自動加入這個多播組。
運行ifconfig -a
, 如果在輸出中有如下的信息,則當前的內核支持multicast。
如果沒有這樣的信息, 嘗試下面的命令
ifconfig eth0 multicast
再運行ifconfig -a
, 如果的確沒有UP BROADCAST RUNNING MULTICAST
, 需要重新編譯內核。
設置內核配置如下:
- CONFIG_IP_MULTICAST=y
- CONFIG_IP_ROUTER=y
- CONFIG_IP_MROUTE=y
- CONFIG_NET_IPIP=y
默認Red Hat / Fedora/ Cent OS內核都支持multicast。 - ====
http://blog.chinaunix.net/uid-31125416-id-5705162.html
2.2 實現IP組播的前提條件
實現IP組播傳輸,則組播源和接收者以及兩者之間的下層網絡都必須支持組播。這包括以下幾方面:
●主機的TCP/IP實現支持發送和接收IP組播;
●主機的網絡接口支持組播;
●有一套用於加入、離開、查詢的組管理協議,即IGMP(v1,v2);
●有一套IP地址分配策略,並能將第三層IP組播地址映射到第二層MAC地址;
●支持IP組播的應用軟件;
●所有介於組播源和接收者之間的路由器、集線器、交換機、TCP/IP棧、防火牆均需支持組播;
http://stackoverflow.com/questions/379015/udp-broadcast-packets-across-subnets
Yes, and no.
It's actually do-able, so long as the intervening routers don't have no ip directed-broadcasts
or similar configured. However these days that's the default because allowing normal broadcasts to traverse routers is a DoS problem.
If you really want to broadcast across subnets then you should be using IP Multicast instead. That still requires that the intervening routers are configured appropriately, but it is the "right" way to do it.
=============================================
http://www.kohala.com/start/mcast.api.txt
-
Sending IP Multicast Datagrams 發送方
IP multicasting is currently supported only on AF_INET sockets of type SOCK_DGRAM and SOCK_RAW, and only on subnetworks for which the interface driver has been modified to support multicasting. To send a multicast datagram, specify an IP multicast address in the range 224.0.0.0 to 239.255.255.255 as the destination address in a sendto() call.
By default, IP multicast datagrams are sent with a time-to-live (TTL) of 1, which prevents them from being forwarded beyond a single subnetwork.
Multicast datagrams with TTL greater than one may be delivered to more than one subnet if there are one or more multicast routers attached to the first-hop subnet. 組播包想跨域子網,除了TTL大於1,還需要子網間的路由器對組播的支持。
multicast datagrams with initial TTL 0 are restricted to the same host multicast datagrams with initial TTL 1 are restricted to the same subnet multicast datagrams with initial TTL 32 are restricted to the same site multicast datagrams with initial TTL 64 are restricted to the same region multicast datagrams with initial TTL 128 are restricted to the same continent multicast datagrams with initial TTL 255 are unrestricted in scope.
The multicast router accompanying this release refuses to forward any multicast datagram with a destination address between 224.0.0.0 and 224.0.0.255, inclusive, regardless of its TTL. This range of addresses is reserved for the use of routing protocols and other low-level topology discovery or maintenance protocols, such as gateway discovery and group membership reporting. The current specification for IP multicasting requires this behavior only for addresses 224.0.0.0 and 224.0.0.1; 路由器拒絕轉發[224.0.0.0, 224.0.0.255]之間的組播報文,無論TTL是什么值。因為這些地址作為保留地址,有特殊用處。
Each multicast transmission is sent from a single network interface, even if the host has more than one multicast-capable interface. 【組播數據始終只能由同一個網卡發出去,即使它是個多網卡機器】
(If the host is also serving as a multicast router, a multicast may be FORWARDED to interfaces other than originating interface, provided that the TTL is greater than 1.) 如果發送組播數據的主機它同時還是一個組播路由器,只要TTL大於1,組播數據可能會從另外的網卡上forward出去。
The system manager establishes the default interface to be used for multicasting as part of the installation procedure, described below. 系統管理員在安裝系統時會指定默認的組播網卡。
A socket option is available to override the default for subsequent transmissions from a given socket: struct in_addr addr; setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr)) //通過該API可以覆蓋默認的組播數據發送網卡。 where "addr" is the local IP address of the desired outgoing interface.
An address of INADDR_ANY may be used to revert to the default interface. 重新設置INADDR_ANY可以恢復默認的組播網卡設置。
The local IP address of an interface can be obtained via the SIOCGIFCONF ioctl. //獲取網卡IP的方法
To determine if an interface supports multicasting, fetch the interface flags via the SIOCGIFFLAGS ioctl and see if the IFF_MULTICAST flag is set. //查看網卡是否支持組播,通常應用程序沒必要使用該選項,因為該選項主要是給路由器等底層網絡設備使用的。
(Normal applications should not need to use this option; it is intended primarily for multicast routers and other system services specifically concerned with internet topology.)
If a multicast datagram is sent to a group to which the sending host itself belongs (on the outgoing interface), a copy of the datagram is, by default, looped back by the IP layer for local delivery.
如果發送方向一個組播組發送了一個組播數據,但發送方本身自己也加入了那個組播組,默認的行為是,IP層會拷貝一份數據包loop back給自己。
Another socket option gives the sender explicit control over whether or not subsequent datagrams are looped back: u_char loop; setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) //同樣,也存在一個選項可以控制,是否接收loop back回來的數據包拷貝。 where "loop" is 0 to disable loopback, and 1 to enable loopback. This option provides a performance benefit for applications that may have no more than one instance on a single host (such as a router or a mail demon), by eliminating the overhead of receiving their own transmissions. 對於那些只扮演一個組播角色的主機來說,禁用loop back是一種性能優化,減少了不必要的環路數據的傳輸。
It should generally not be used by applications for which there may be more than one instance on a single host (such as a conferencing program) or for which the sender does not belong to the destination group (such as a time querying program). 但對於那些同時扮演了多個組播角色(既是發送方,又是接收方)的主機來說,(例如視頻會議:因為發送一個組播視頻數據,同時發送方自身也需要把視頻數據展現出來),例如組播數據的發送方自身並不屬於目的組播組(例如時間查詢程序),類似這樣的情形,通常並不推薦應用程序禁用loop back選項。
A multicast datagram sent with an initial TTL greater than 1 may be delivered to the sending host on a different interface from that on which it was sent, if the host belongs to the destination group on that other interface.
The loopback control option has no effect on such delivery. 如果被發送的組播數據的TTL大於1,並且該主機通過另外一個網卡加入到了目標組播組內,它可能會從不同的網卡上收到loop back回來的組播數據, 這中情況loopback選項不起作用。
有可能發組播數據是一個網卡,收組播數據是另外一個網卡。
setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr)) 控制的是發送組播數據的網卡
struct ip_mreq mreq;
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) 控制的是接收組播數據的網卡
-
Receiving IP Multicast Datagrams 接收方
Before a host can receive IP multicast datagrams, it must become a member of one or more IP multicast groups. //在能接收組播數據前,必須先加入對應的組播組
A process can ask the host to join a multicast group by using the following socket option: struct ip_mreq mreq; setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) where "mreq" is the following structure: struct ip_mreq { struct in_addr imr_multiaddr; /* multicast group to join */ struct in_addr imr_interface; /* interface to join on */ 加入組播組時所使用的網卡 } Every membership(組播組) is associated with a single interface, and it is possible to join the same group on more than one interface. 每一個組都必須綁定一個網卡,可以把多個網卡同時加入同一個組播組
"imr_interface" should be INADDR_ANY to choose the default multicast interface, or one of the host's local addresses to choose a particular (multicast-capable) interface.
imr_interface字段要么是INADDR_ANY(使用系統默認的網卡加入組),要么是本機的某個網卡對應的IP。
Up to IP_MAX_MEMBERSHIPS (currently 20) memberships may be added on a single socket. 一個網卡最多可以加入20個組播組。
To drop a membership, use: struct ip_mreq mreq; setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) where "mreq" contains the same values as used to add the membership. The memberships associated with a socket are also dropped when the socket is closed or the process holding the socket is killed. //當socket被關閉,或者socket所在的進程結束,該socket將會自動離開組播組。
However, more than one socket may claim a membership in a particular group, and the host will remain a member of that group until the last claim is dropped. The memberships associated with a socket do not necessarily determine which datagrams are received on that socket. (socket被加入了某個組播組,但並不代表就能從該socket上接收到組內的組播數據)
Incoming multicast packets are accepted by the kernel IP layer if any socket has claimed a membership in the destination group of the datagram;
however, delivery of a multicast datagram to a particular socket is based on the destination port (or protocol type, for raw sockets), just as with unicast datagrams.
組播數據能不能被socket所收到,由數據包中的目標端口來決定,就和UDP單播一樣。
To receive multicast datagrams sent to a particular port, it is necessary to bind to that local port, leaving the local address unspecified (i.e., INADDR_ANY).
為了能夠收到被發往某個端口的組播數據報,必須把sock綁定到對應的本地端口,本地地址保留為INADDR_ANY(表示我能接收任何地址發向特定端口的數據)。
http://www.cnblogs.com/my_life/articles/6065752.html
More than one process may bind to the same SOCK_DGRAM UDP port if the bind() is preceded by: 多個進程可以綁定同一個UDP端口,如果在此之前進行了SO_REUSEADDR的設置 int one = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) In this case, every incoming multicast or broadcast UDP datagram destined to the shared port is delivered to all sockets bound to the port. 這種情況下,綁定在該端口上的所有socket都可以收到發往該端口的組播和廣播UDP報文。
For backwards compatibility reasons, THIS DOES NOT APPLY TO INCOMING UNICAST DATAGRAMS -- unicast datagrams are never delivered to more than one socket, regardless of how many sockets are bound to the datagram's destination port.
為了向后兼容,上述理論並不適用於incoming單播udp數據報, 單播UDP絕對不會被發往多個scoket,只能發往一個socket, 無論多少個socket綁定在了同一個目標端口上。
http://www.cnblogs.com/my_life/articles/4397672.html
SO_REUSEADDR可以用在以下四種情況下。
(摘自《Unix網絡編程》卷一,即UNPv1)
1、當有一個有相同本地地址和端口的socket1處於TIME_WAIT狀態時,而你啟動的程序的socket2要占用該地址和端口,你的程序就要用到該選項。
2、SO_REUSEADDR允許同一port上啟動同一服務器的多個實例(多個進程)。但每個實例綁定的IP地址是不能相同的。在有多塊網卡或用IP Alias技術的機器可以測試這種情況。
3、SO_REUSEADDR允許單個進程綁定相同的端口到多個socket上,但每個socket綁定的ip地址不同。這和2很相似,區別請看UNPv1。
4、SO_REUSEADDR允許完全相同的地址和端口的重復綁定。但這只用於UDP的多播/組播,不用於TCP。
SOCK_RAW sockets do not require the SO_REUSEADDR option to share a single IP protocol type. The definitions required for the new, multicast-related socket options are found in <netinet/in.h>. All IP addresses are passed in network byte-order. A final multicast-related extension is independent of IP: two new ioctls, SIOCADDMULTI and SIOCDELMULTI, are available to add or delete link-level (e.g., Ethernet) multicast addresses accepted by a particular interface. The address to be added or deleted is passed as a sockaddr structure of family AF_UNSPEC, within the standard ifreq structure.
These ioctls are for the use of protocols other than IP, and require superuser privileges. 這兩個ioctls不是給IP協議使用的
A link-level multicast address added via SIOCADDMULTI is not automaticallydeleted when the socket used to add it goes away; it must be explicitly deleted. It is inadvisable to delete a link-level address that may be in use by IP. (These ioctls already exist in SunOS and Ultrix; they are new to BSD Unix.) Drivers that have been modified to support multicasting also support the IFF_PROMISC and IFF_ALLMULTI interface flags, to the degree possible. The kernel modification required to support Van Jacobson's traceroute program is also included in this release. Examples of usage of the above facilities can be found in the programs accompanying this distribution, such as "ping", "mtest" and "rwhod".
5. ESTABLISHING A DEFAULT MULTICAST INTERFACE 設置默認的組播網卡
Selection of the default multicast interface is controlled via the kernel (unicast) routing table. If there is no multicast route in the table, all multicasts will, by default, be sent on the interface associated with the
default gateway. 組播默認的網卡的選擇是由路由表控制的。如果路由表中沒有組播路由表,所有的組播默認會被發往默認網關所綁定的網卡。
If that interface does not support multicast, attempts to send will receive an ENETUNREACH error. //如果網卡不支持組播,返回ENETUNREACH錯誤 A route may be added for a particular multicast address or for all multicast addresses, to direct them to a different default interface.
For example, to specify that multicast datagrams addressed to 224.0.1.3 should, by default, be sent on the interface with local address 36.2.0.8,
use the following: /etc/route add 224.0.1.3 36.2.0.8 0 //指定某個特定的組播地址所使用的網卡
To set the default for all multicast addresses, other than those with individual routes, to be the interface with local address 36.11.0.1,
use: /etc/route add 224.0.0.0 36.11.0.1 0 //為所有的組播地址指定所使用的網卡
If you point a multicast route at an interface that does not support multicasting, an attempt to multicast via that route will receive an ENETUNREACH error.
If needed, these commands normally would be added to the /etc/rc.ip or /etc/rc.local file, to take effect every time the system is booted. 9. MTEST The mtest directory contains a small program for testing the multicast membership sockopts and ioctls. It accepts the following commands, interactively: j g.g.g.g i.i.i.i - join IP multicast group l g.g.g.g i.i.i.i - leave IP multicast group a ifname e.e.e.e.e.e - add ether multicast address d ifname e.e.e.e.e.e - del ether multicast address m ifname 1/0 - set/clear ether allmulti flag p ifname 1/0 - set/clear ether promisc flag q - quit where g.g.g.g is an IP multicast address, e.g., 224.0.2.1 i.i.i.i is the IP address of a local interface or 0.0.0.0 ifname is an interface name, e.g., qe0 e.e.e.e.e.e is an Ethernet address in hex, e.g., 1.0.5e.0.2.1 1/0 is a 1 or a 0, to turn the flag on or off The "p" command to change the promiscuous flag does not work under SunOS, because it uses a different ioctl for that purpose. Mtest is useful for establishing targets for multicast ping testing. The results of mtest filter manipulation can be seen by using the "netstat -nia" command (see next section).