网络编程中有时明明用eth0的地址来bind一个udp套接口, 可是发出去的包却是从eht1走的, 在网上找到这么一段话解释该问题:
          在多 IP/网卡主机上,UDP 包/协议会自动根据路由最优来选择从哪个网卡发数据包出去,即使你在此之前把该 SOCKET 绑定到了另一个网卡上。这样一来,如果你执行了绑定,则在 UDP 包中所代表的源 IP 字段可能不是你的数据包真正发出的地址。
比如:你有两个网卡分别为:A—192.168.1.100; B-192.168.2.100; mask-255.255.255.0 
此时你如果将一 UDP 套接字 S 绑定到了 A 上,但是要发的目的地址为 192.168.2.110,这时包实际是从网卡 B 上发出去的(根据路由最优原则),但在包头的结构里面,由于 BIND 的缘故,可能指向的源地址为 A。这样源 IP 地址就产生了与实际不相符的错误。
  要解决这种问题, 可以把套接字绑定到一个指定的网络设备, "eth0", "ppp0"等.
 

三个示例:

 
1. example(TCP, UDP, RAW):
 

int sock;
struct ifreq ifr;
sock = socket(AF_INET, SOCK_DGRAM, 0);
memset(&ifr, 0x00, sizeof(ifr));
strncpy(ifr.ifr_name, "eth0", IFNAMSIZE);
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifr, sizeof(ifr));

2. example(PACKET):
 

int sock;
struct sockaddr_ll sl;
struct ifreq ifr;
sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IPV6));
memset(&sl, 0x00, sizeof(sl));
memset(&ifr, 0x00, sizeof(ifr));
sl.sll_family = AF_PACKET;
sl.sll_protocol = htons(ETH_P_IPV6);
strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));
ioctl(fd, SIOCGIFINDEX, &ifr);
sl.sll_ifindex = ifr.ifr_ifindex;
bind(fd, (struct sockaddr *)&sl, sizeof(sl));

3. example(PACKET):
 

int sock;
struct sockaddr addr;
sock = socket(PF_PACKET, SOCK_PACKET, ETH_P_IP);
memset(&addr, 0x00, sizeof(addr));
addr.sa_family = PF_PACKET;
strncpy(addr.sa_data, "eth0", sizeof(addr.sa_data));
bind(sock, &addr, sizeof(addr));

针对SO_BINDTODEVICE套接口选项,man(7)手册有如下说明:
SO_BINDTODEVICE
Bind  this  socket  to  a particular device like “eth0”, as specified in the passed interface name.  If the name is an empty string or the option length is zero, the socket device binding  is  removed.   The  passed option  is a variable-length null-terminated interface name string with the maximum size of IFNAMSIZ.  If a socket is bound to an interface, only packets received from that particular interface are processed by  the socket.  Note  that  this  only works for some socket types, particularly AF_INET sockets.  It is not supported for packet sockets (use normal bind(8) there).

参考信息:
 

绑定socket描述符到一个网络设备的更多相关文章

  1. linux一切皆文件之tcp socket描述符(三)

    一.知识准备 1.在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件(比如:块设备,socket套接字,pipe队列) 2.操作这些不同的类型就像操作文件一样,比如增删改查等 二.环境准备 ...

  2. linux一切皆文件之Unix domain socket描述符(二)

    一.知识准备 1.在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件(比如:块设备,socket套接字,pipe队列) 2.操作这些不同的类型就像操作文件一样,比如增删改查等 3.主要用于 ...

  3. 【读书笔记】socket描述符选项[SOL_SOCKET]

    #include <sys/socket.h>    int setsockopt( int socket, int level, int option_name,             ...

  4. vue组件双向绑定.sync修饰符的一个坑

    我们知道组件是单项的,但是有时候需要双向,这时候我们可以使用.sync修饰符,但今天遇到一个坑,一直不成功,花了半小时试出来的.... 在编程的时候我们很习惯冒号后面跟着空格.而.sync双向绑定需要 ...

  5. linux内核中的文件描述符(二)--socket和文件描述符

    http://blog.csdn.net/ce123_zhouwei/article/details/8459730 Linux内核中的文件描述符(二)--socket和文件描述符 Kernel ve ...

  6. python描述符理解

    Python中的描述符是一个相对底层的概念 descriptor Any object which defines the methods get(), set(), or delete(). Whe ...

  7. 【转载】Python 描述符简介

    来源:Alex Starostin 链接:www.ibm.com/developerworks/cn/opensource/os-pythondescriptors/ 关于Python@修饰符的文章可 ...

  8. linux专题一之文件描述符、重定向、管道符、tee命令

    本节讨论一下几个问题: 1. 文件描述符. 2. 重定向. 3. 管道符 4. tee的用法. 1. 文件描述符. 在linux系统中一切皆文件.文件夹和设备都是文件.如何用来区别不同的文件呢?这里的 ...

  9. linux文件描述符--转载

    转自:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录 ...

随机推荐

  1. C++ windows 函数讲解(一)获得屏幕分辨率

    先上代码: #include<bits/stdc++.h> #include<windows.h> using namespace std; int main() { int ...

  2. node 在centos 6.5 上 安装过程中出现/usr/lib64/libstdc++.so.6: version 'GLIBCXX_3.4.19' not found问题的解决

    node  在centos 6.5 上 安装过程中出现/usr/lib64/libstdc++.so.6: version 'GLIBCXX_3.4.19' not found问题的解决 在linux ...

  3. Windows 10 64位操作系统 下安装、连接测试sqlite3 sql基本操作 增删改

    一.下载sqlite安装包 1:详细下载安装版本可见官网:https://www.sqlite.org/download.html 2:百度盘分享连接:https://pan.baidu.com/s/ ...

  4. markdown写作系统

    markdown 电脑本地使用typora,可保存为md文件直接上传到有道云笔记中 直接使用博客园做为图床,可以存为草稿,然后把复制连接 有道云笔记 粘贴博客园的图片连接

  5. 接口测试checklist

    静态测试 接口文档与设计文档对应 接口定义 接口定义与数据库定义 业务功能测试 系统全流程验证 逆向全流程验证 事务性测试 边界值测试 业务规则边界值 场景分析合理长度 场景分析合理数据量 输入.输出 ...

  6. CF710F-String Set Queries【AC自动机,二进制分组】

    正题 题目链接:https://www.luogu.com.cn/problem/CF710F 题目大意 \(T\)次操作 往集合中加入一个字符串 往集合中删除一个字符串 给出一个模式串求出现的集合里 ...

  7. Docker小白到实战之Docker网络简单了解一下

    前言 现在对于Docker容器的隔离性都有所了解了,但对容器IP地址的分配.容器间的访问等还是有点小疑问,如果容器的IP由于新启动导致变动,那又怎么才能保证原有业务不会被影响,这就和网络有挂钩了,接下 ...

  8. WPF进阶技巧和实战01-小技巧

    Svg在WPF中的使用 方法1:拷贝svg中的部分代码转换成Geometry(作为Path的Data使用) 在vs或者直接打开svg,看到如下代码: <?xml version="1. ...

  9. Winform 窗体自适应

    前言 在使用 Winform 开发过程中,经常发些因为显示器分辨率.窗体大小改变,控件却不能自适应变化,几经查找资料,和大佬的代码.经过细小修改,终于可以让窗体在外界影响下,窗体内背景图片.控件都会自 ...

  10. CSS3思维导图