Socket Communication on Specified Network Interface in Linux

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).

Leave a Comment