Send multicast datagram in Linux

Source: Internet
Author: User
Tags htons
Let's take the multicast data sent to UDP as an example. In fact, the difference between sending a UDP multicast datagram and sending a unicast UDP datagram is not big.
First, in the myudp_sendmsg function, if the source address of the sending interface is not determined and the target address is a multicast address, the source address uses inet_sock-> mc_addr. The source address of the sending interface is determined by inet_sock-> saddr. If inet_sock-> saddr is found to be zero, the inet_sock-> mc_addr value is used.
Use the preceding Article We can understand that the function of the BIND system call is to specify the sending source address and Receiving address for a local set of interfaces (that is, to bind a local set of interfaces to a local network device interface ). The multicast option ip_multicast_if is used to specify the sending interface of multicast datagram. The functions of the two seem to be repeated. Bind affects the members rcv_saddr, saddr, and sport of inet_sock, which respectively indicate the Receiving address (if this address is specified as the destination address in the input datagram header, it will be received ), sending source address (the address of a local network device interface), the port for sending and receiving. For unicast, it is clear that rcv_saddr = saddr, because generally, an application Program A network device interface is used to send and receive data. However, if the application needs to bind a multicast address and port to a local interface, the bind system calls rcv_addr = multicast address and sport = port, the saddr is equal to 0, but the protocol stack must have a local network device interface to send multicast datagram. Without saddr, the protocol stack does not know which device to send the datagram, this task is left with the ip_multicast_if option, which assigns values to inet_sock members mc_addr and mc_index, and specifies the local interface for sending multicast data packets.
It is possible that if our application wants to send multicast datagram to the network through a local network device interface, and does not care about receiving the datagram from this group (may come from other hosts, when the loop is started, it may also come from itself). We can simply bind the sending socket to a local interface through bind, and then send a datagram to the multicast address, however, it feels like you are standing outside the group (not in this group) and sending a datagram to the group, Source code As follows:
# Include <stdio. h>
# Include <string. h>
# Include <sys/types. h>
# Include <sys/socket. h>
# Include "my_inet.h"
# Include <Linux/in. h>

# Define maxbuckets 256
# Define Puerto 5000
# Define Grupo "224.0.1.1"
Int main (void)
{
Int FD;
Struct sockaddr_in SRV, local;
Char Buf [maxbuf];
Memset (& SRV, 0, sizeof (SRV ));

SRV. sin_family = my_af_inet;
SRV. sin_port = htons (Puerto );

Local. sin_family = af_inet;
Local. sin_port = htons (16000 );
Inet_aton ("172.16.48.2", & (local. sin_addr ));

If (inet_aton (Grupo, & srv. sin_addr) <0) {
perror ("inet_aton");
return-1;
}< br> If (FD = socket (my_af_inet, sock_dgram, my_ipproto_udp) <0) {
perror ("socket");
return-1;
}< br> If (BIND (FD, (struct sockaddr *) & Local, sizeof (local) <0) {
perror ("BIND:");
return-1;
}

While (fgets (BUF, maxbuf, stdin )){
If (sendto (FD, Buf, strlen (BUF), 0, (struct sockaddr *) & SRV, sizeof (SRV) <0 ){
Perror ("recvfrom ");
} Else {
Fprintf (stdout, "enviado a % s: % s", Grupo, Buf );
}
}
}
Because the bind system call sets rcv_addr, a member of inet_sock, as the address of the local network device interface 172.16.48.2, this program can only send data packets and cannot receive data packets sent to the group 224.0.1.1. If you want the sender to receive the message as well, you should change the program as follows:
# Include <stdio. h>
# Include <sys/types. h>
# Include <sys/socket. h>
# Include <string. h>
# Include <ARPA/inet. h>
# Include "my_inet.h"

# Define maxbuckets 256
# Define Puerto 5000
# Define group "224.0.1.1"
Int main (void)
{
Int FD;
Struct sockaddr_in SRV, local;
Struct in_addr if_req;
Char Buf [maxbuf];

SRV. sin_family = my_af_inet;
SRV. sin_port = htons (Puerto );
Inet_aton (group, & srv. sin_addr );

Local. sin_family = My _ af_inet;
Local. sin_port = htons (16000 );
Inet_aton (group, & (local. sin_addr ));

If (FD = socket (af_inet, sock_dgram, ipproto_udp) <0 ){
Perror ("socket ");
Return-1;
}
If (BIND (FD, (struct sockaddr *) & Local, sizeof (local) <0 ){
Perror ("BIND :");
Return-1;
}
Inet_aton ("172.16.48.2", & (if_req ));
If (setsockopt (FD, sol_ip, ip_multicast_if, & if_req, sizeof (struct in_addr) <0 ){
Perror ("setsockopt :");
Return-1;
}
While (fgets (BUF, maxbuf, stdin )){
If (sendto (FD, Buf, strlen (BUF), 0, (struct sockaddr *) & SRV, sizeof (SRV) <0 ){
Perror ("sendto ");
} Else {
Fprintf (stdout, "enviado a % s: % s", group, Buf );
}
}
}
This time, the local interface is bound to a multicast address, so that this application can not only send multicast data, it can also accept the datagram sent to port 16000 in the same group (it is best to add an ip_add_membership option operation). However, when the BIND multicast address is set, only the Receiving address is set to the multicast address, the sending source address is not set. Therefore, you must use the ip_multicast_if interface to specify a sending interface (172.16.48.2 is specified in the program, that is, the eth0 interface ).
These two programs can work normally in the current my_inet module, but they actually send the call Code It is the UDP unicast code, which basically works normally, but the unicast Code does not have much special processing for multicast, such as Multicast Route verification and loop sending.
In the next article, we will add the code for sending multicast datagram to the module and provide analysis.
Note: strictly speaking, the above two programs are all faulty. The set interface of program 1 will receive the data sent to port 16000 of the local 172.16.48.2 interface and block the data in the receiving queue of the Set interface, program 2 receives the data sent to port 16000 of the group 224.0.1.1 and blocks the data in the receiving queue of the Set interface.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.