In many devices running Linux, there are multiple network interfaces. How can we ensure that our program’s Socket communication is only effective on a specified network interface?We can bind the Socket to the desired network interface (e.g., eth1, modify as needed) using the following code:
#define INTERFAXENAME "eth1"
struct ifreq interface;strncpy(interface.ifr_ifrn.ifrn_name, INTERFAXENAME, sizeof(INTERFAXENAME));if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) { perror("SO_BINDTODEVICE failed");}
Below is a complete demo program source code for reference:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <netinet/in.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <sys/ioctl.h>
#define BUF_SIZE 1024
#define INTERFAXENAME "eth1"
int sock;
void * network_recv_thread(void * arg){ int n = 0; char buff[BUF_SIZE]; struct sockaddr_in peer; int len = sizeof(peer);
while(1) { n = recvfrom(sock, buff, BUF_SIZE, 0, (struct sockaddr *)&peer, &len); if (n>0) { buff[n] = 0; printf("received:"); puts(buff); } else if (n==0) { printf("server closed\n"); close(sock); break; } else if (n == -1) { perror("recvfrom"); close(sock); break; } }
return NULL;}
int main(int argc, char *argv[]){ int ret = 0;
if (argc != 3) { printf("Usage: %s ip port\n", argv[0]); exit(1); }
printf("This is a UDP client\n");
if ( (sock=socket(AF_INET, SOCK_DGRAM, 0)) <0) { perror("socket"); exit(1); }
struct ifreq interface; strncpy(interface.ifr_ifrn.ifrn_name, INTERFAXENAME, sizeof(INTERFAXENAME)); if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) { perror("SO_BINDTODEVICE failed"); }
struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(atoi(argv[2])); addr.sin_addr.s_addr = inet_addr(argv[1]); if (addr.sin_addr.s_addr == INADDR_NONE) { printf("Incorrect ip address!"); close(sock); exit(1); }
pthread_t pid; ret = pthread_create(&pid, NULL,network_recv_thread, NULL); if (ret) { printf("Create pthread error!\n"); return 0; }
char buff[BUF_SIZE]; int n = 0;
while (1) { gets(buff); n = sendto(sock, buff, strlen(buff), 0, (struct sockaddr *)&addr, sizeof(addr)); if (n < 0) { perror("sendto"); close(sock); break; } }
pthread_join(pid, NULL); return 0;}
After running the above example, you can use some network debugging tools (such as SocketTool) to run a UDP Server, and then run this program in the format “Program_Name Server_IP Server_Port” for debugging and verification (or you can write your own Server program as well).