| How to detect the IP change of a interface address in the socket programming? Dear all,
There is a socket programming issue as below. Please help to provide your good idea for our reference. Thanks!
In our linux system, there are two network cards with two different IP addresses (for example: 10.1.1.1 and 20.2.2.2). We write a server program to bind a socket with one of above interfaces (10.1.1.1) for receiving the requests from any client. After a period of operation, the IP address of such interface would be chagned from 10.1.1.1 to 30.3.3.3. The original binding for socket would not identify such change and fail to communicate with client. Is there any good solution to detect the change of interface address and then re-bind the socket to new IP address?
In addition, I use the following code to do the tests. The socket is binded to the IP (10.0.2.15) of only-one interface. And, then it is suspended to wait incoming packets by the select() API.
1). The code would be executed successfully when interface's IP is 10.0.2.15.
2). If I change the IP to 10.0.2.16 and run the program again, the code is failed to execute due the failured of binding.
3). After the code is executed, I change the interface's IP. There's no any response for that program. That program is still suspended in the select(().
4). After the code is executed, I make the interface down. There's no any response for that program. That program is still suspended in the select(().
Do you have any good idea to detect the IP change for specific binding? Thanks!
=== TEST CODE === ======================================
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#define BUFLEN 512
#define PORT 9930
#define NPACK 10
int main(void)
{
struct sockaddr_in si_me, si_other;
int s, i, r, slen=sizeof(si_other);
int nfds;
fd_set rfds;
char buf[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1 )
return(-1);
memset((void*)&si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(0x0A00020F);
if ( bind(s, (const struct sockaddr*)&si_me, sizeof(si_me)) == -1 )
{
printf("* fail to bind()\n");
return(-1);
}
FD_ZERO(&rfds);
FD_SET(s, &rfds);
nfds = s + 1;
r = select(nfds, &rfds, (fd_set*)0, &rfds, (struct timeval*)0);
if ( r < 0 )
{
printf("* select() error: %d, (errno=%d.%s)\n", r, errno, strerror(errno));
return (-2);
}
if (recvfrom(s, (void*)buf, BUFLEN, 0, (struct sockaddr*)&si_other, &slen)==-1)
{
printf("- Received packet from %s:%d\nData: %s\n\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
}
close(s);
return (0);
} |