Broadcast data cannot be received after UDP socket is bound to an IP address.

Source: Internet
Author: User
Tags htons

Broadcast data cannot be received after UDP socket is bound to an IP address.

Fannyth05-11-10, because my program is running on a machine with multiple NICs, So I bound the IP address of the NIC to the socket
Server_addr.sin_addr.s_addr = inet_addr (servip); but then the broadcast data cannot be received? At the same time, when I was bound to a broadcast address, I found that the client received data twice consecutively. Why?

The following is my test procedure:

// Server. cpp
# Include <stdio. h>
# Include <sys/socket. h>
# Include <netinet/in. h>
# Include <ARPA/inet. h>
# Include <netdb. h>
# Include <string. h>

Char * host_name = "192.168.0.255 ";
Int Port = 10051;

Int main (void)
{
Struct sockaddr_in serv_addr, ADDR;
Char Buf [256];

Int sockfd = socket (af_inet, sock_dgram, 0 );
If (sockfd =-1)
{
Perror ("error: socket ";
Return-1;
}
Memset (& ADDR, 0, sizeof (ADDR ));
ADDR. sin_family = af_inet;
ADDR. sin_port = htons (port );
ADDR. sin_addr.s_addr = inet_addr (host_name); // htonl (inaddr_any );//

Int BD = BIND (sockfd, (struct sockaddr *) & ADDR, sizeof (struct sockaddr_in ));
While (1)
{
Int Len = sizeof (serv_addr );
Memset (& serv_addr, 0, Len );
Int ret = recvfrom (sockfd, Buf, sizeof (BUF), 0, (struct sockaddr *) & serv_addr, (socklen_t *) & Len );

Printf ("Recv = % d Buf = % s
", RET, Buf );
Printf ("recvieip: % s recive port: % d
", Inet_ntoa (serv_addr.sin_addr ),
Ntohs (serv_addr.sin_port ));
Ret = sendto (sockfd, Buf, sizeof (BUF), 0, (struct sockaddr *) & serv_addr, sizeof (struct sockaddr_in ));
}

}

// Client. cpp

# Include <stdio. h>
# Include <sys/socket. h>
# Include <netinet/in. h>
# Include <ARPA/inet. h>
# Include <netdb. h>
# Include <string. h>

Char * host_name = "192.168.0.255 ";

Int Port = 10051;
Int main (void)
{
Int sockfd = socket (af_inet, sock_dgram, 0 );
If (sockfd =-1)
{
Perror ("error: socket ";
Return-1;
}

Struct sockaddr_in serv_addr;
Memset (& serv_addr, 0, sizeof (serv_addr ));
Serv_addr.sin_family = af_inet;
Serv_addr.sin_port = htons (port );
Serv_addr.sin_addr.s_addr = inet_addr (host_name );
Int so_broadcast;
Setsockopt (sockfd, sol_socket, so_broadcast, & so_broadcast,
Sizeof (so_broadcast ));

Char Buf [256] = "client .............";
Sockaddr from;
Int Len;
Sendto (sockfd, Buf, sizeof (BUF), 0, (struct sockaddr *) & serv_addr, sizeof (struct sockaddr_in ));
While (1)
{
Recvfrom (sockfd, Buf, sizeof (BUF), 0, (struct sockaddr *) & serv_addr, (socklen_t *) & Len );

Printf ("server Buf = % s
", Buf );
}
}

Haohao_h05-11-10, you give your server a broadcast address to tell it how to accept data! Fannyth05-11-10, you give your server a broadcast address to tell it how to accept data!

Because I want to accept the broadcast data. If the IP address specified by the channel is bound, I cannot receive the data sent from the client. Now I have to bind the broadcast address and receive the same data twice each time. my two IP addresses are 192.168.0.2 and 196.168.0.172.

Haohao_h05-11-11, because I want to accept broadcast data if the bound channel specifies the IP address, can not receive the data sent from the client, I now bind broadcast address each time will receive the same data twice. my two IP addresses are 192.168.0.2 and 196.168.0.172.
I recommend you read a book, Richard Stevens's UNIX Network Programming volume 1. X1105-11-11, dual network card is best not to set into a network segment

You have two NICs in one CIDR block. As a result, both NICs receive broadcast data.

Fannyth05-11-11, dual network card is best not to set into a network segment

You have two NICs in one CIDR block. As a result, both NICs receive broadcast data.

Yes, but when the program is used by others, it is difficult to ensure that the dual Nic of another machine is in a network segment. I want to know if the broadcast package cannot be accepted after the socket is bound to the specified address.

X1105-11-11, should not
Int so_broadcast = 1;
Setsockopt (sockfd, sol_socket, so_broadcast, & so_broadcast, sizeof (so_broadcast); [u] Fannyth05-11-11, should not
Int so_broadcast = 1;
Setsockopt (sockfd, sol_socket, so_broadcast, & so_broadcast, sizeof (so_broadcast); [u]

I tried it. I bound the socket to an IP address on the receiver, and added this sentence on the receiver, but still failed to receive the broadcast package.

X1105-11-11, well, bind to the NIC address is not allowed to receive broadcast packets

Then you should stop bind.

Westwind05-11-11, well, bind to the NIC address is not allowed to receive broadcast packets

Then you should stop bind.

The UDP broadcast delivery rules are as follows:
If the bloadcase option is not set, do not deliver.
This interface is not delivered if the BIND port does not match
If inaddr_any is not bound
The bind address and the destination address must match to deliver:
That is to say, you must bind a broadcast address or bind inaddr_any
Third
If your UDP calls connect
The source address and source port do not match and are not delivered.
Otherwise deliver

You can set the disable broadcast capability of one network card.

Fannyth05-11-11, it seems that I want to reconsider the idea of solving my problem; I will repeat the problem again, we look at the good ideas to solve.

Because my program runs on a machine with multiple NICs, I want the socket to accept both broadcast data and unicast data. At the same time, broadcast data is accepted only once. Because the server has multiple NICs, and my client does not know its IP address when it starts, the broadcast address sent by the client is 255.255.255.255; so I want to determine whether two soket can be used to accept the broadcast, and the packet is automatically ignored. Is the other one used to accept unicast data? Do you know this is acceptable? Will there be any impact?

Westwind05-11-11, it seems that I want to reconsider the idea of solving my problem; I will talk about the problem again, we look at what good ideas to solve.

Because my program runs on a machine with multiple NICs, I want the socket to accept both broadcast data and unicast data. At the same time, broadcast data is accepted only once. Because the server has multiple NICs, and my client does not know its IP address when it starts, the broadcast address sent by the client is 255.255.255.255; so I want to determine whether two soket can be used to accept the broadcast, and the packet is automatically ignored. Is the other one used to accept unicast data? Do you know this is acceptable? Will there be any impact?

You can do this.

Two UDP sockets
The unicast socket bind inaddr_any and the so_broadcast option is set to 0. At this time, it only accepts unicast datagram.

Broadcast the socket bind without limit 255, and set so_broadcase to 1. At this time, he only accepts UDP broadcast.

To avoid receiving 2-minute copy of the same broadcast, if the two NICs are located in the same subnet, use the ifconfig command to disable the broadcast flag of one of the NICS so that they cannot accept Ethernet broadcast.

You can also use the siocsifflags method of IOCTL to remove the iff_broadcast flag of an interface so that it cannot accept Ethernet broadcast.

Fannyth05-11-11, you can do this.

Two UDP sockets
The unicast socket bind inaddr_any and the so_broadcast option is set to 0. At this time, it only accepts unicast datagram.

Broadcast the socket bind without limit 255, and set so_broadcase to 1. At this time, he only accepts UDP broadcast.

To avoid receiving 2-minute copy of the same broadcast, if the two NICs are located in the same subnet, use the ifconfig command to disable the broadcast flag of one of the NICS so that they cannot accept Ethernet broadcast.

You can also use the siocsifflags method of IOCTL to remove the iff_broadcast flag of an interface so that it cannot accept Ethernet broadcast.

Thank you. You have explained this in detail. I can try it. But if I set another Nic to be unable to Accept Broadcast Data, will it affect other programs? So I want to perform a test while receiving the broadcast data to check whether the received data is received by the specified Nic. If yes, it will be processed; otherwise, it will be discarded; but I do not know how to detect it? What is the impact on efficiency at the same time?

Westwind05-11-12, thanks, you said very detailed, I can try; but I want to set another Nic can not accept broadcast data, will it affect other programs? So I want to perform a test while receiving the broadcast data to check whether the received data is received by the specified Nic. If yes, it will be processed; otherwise, it will be discarded; but I do not know how to detect it? What is the impact on efficiency at the same time?

It is also possible that at least one socket API can return the destination address of the datagram,
Recvmsg
Recvmsg is the underlying implementation of non-svr4 system Recv, recvfrom, readv, and syscall under recvmsg.
However, this function is quite complex. You need to learn how to use it and it cannot be transplanted. At least this method is not provided in windows.

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.