linux下使用setsockopt()函数中的SO 您所在的位置:网站首页 c语言setsockopt10038 linux下使用setsockopt()函数中的SO

linux下使用setsockopt()函数中的SO

#linux下使用setsockopt()函数中的SO| 来源: 网络整理| 查看: 265

SO_BINDTODEVICE可以显示地将某些数据指定从哪个网络设备发送。

此选项的值是一个表示设备名称的字符串,当为空字符串时,套接字绑定到序号为0的网络设备上。当字符串是一个正确的网络设备名称时,则会绑定到此设备上。

如下面代码将套接字s绑定到网卡eth1上:

int s, err; char ifname[] = "eth1"; //绑定的网卡名称 ... ... err = setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, ifname, 5); //将s绑定到网卡eth1上 if(err){ printf("setsockopt SO_BINDTODEVICE failure\n"); }

说明

(1)套接字

套接字是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。

(2)setsockopt()函数

#include #include int setsockopt(int s, int level, int optname, const void *optval, socklen_t *optlen);

s:将要获得或者设置的套接字描述符,可以通过socket()函数获得

level:选项所在协议层(因为要操作套接字层,这里指定为SOL_SOCKET)

optname:选项名

optval:操作的内存缓冲区。指向设置的参数缓冲区

optlen:表示第4个参数的实际长度

函数返回值成功为0,否则为-1,错误代码可以从errno中获得,其含义如下:

EBADF:参数s不是有效的文件描述符。

EFAULT:optval指向的内存并非有效的进程空间的错误。

EINVAL:在调用函数时,optlen无效。

ENOPROTOOPT:指定的协议层不能识别选项。

ENOTSOCK:s描述的不是套接字描述符。

具体代码实现如下,参考:https://blog.csdn.net/fuyuande/article/details/82728734 并在调试中针对一些编译错误做了修改。

#include #include #include #include #include #include #include #include #include #include int main() { struct sockaddr_in addr, raddr; char buffer[] = "hello world"; /* 指定接口 */ struct ifreq nif; //const char *inface = "eno1";//以太网卡10.0.169.122,根据自己的情况修改 const char *inface = "wlp0s20f3";//wifi网卡10.0.188.160,根据自己的情况修改 strncpy(nif.ifr_name, inface,IFNAMSIZ); /* 创建套接字 */ int sock = socket(AF_INET, SOCK_DGRAM, 0); if (-1 == sock) { printf("create socket fail \r\n"); return -1; } else { printf("create socket success \r\n"); } //192.168.1.123是目标IP地址,根据自己的情况修改 if (inet_aton("192.168.1.123", &addr.sin_addr) != 1) { printf("addr convert fail \r\n"); close(sock); return -1; } addr.sin_family = AF_INET; addr.sin_port = htons(8000); /* 绑定接口 */ if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&nif, sizeof(nif)) printf("bind interface success \r\n"); } /* 发送 */ sendto(sock, buffer, sizeof(buffer), 0, ((struct sockaddr *)&addr),sizeof(addr)); close(sock); return 0; }

调试,在终端中输入sudo tcpdump -i any port 8000 -n

使用sudo运行程序,分别为以太网和wifi的情况,即可看到结果: 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有