这片文章的要解决的问题和解决方法在标题就已经解释得很清楚了。这里记录一下我的解决过程(还是各种查资料)。
(这个解决方法适不适用于跨网段就不知道了,可以试试)
我的工作环境是服务端和客户端都是多网卡。我需要使服务端的网卡10.0.0.1与客户端的网卡10.0.0.2之间进行通信。在代码里面我也确实是这样绑定的。但是我遇到了与图片中描述一样的问题:
网上给出的答案大体是分别绑定IP,把套接字绑定到一个指定的网络设备,比如"eth0"、“ppp0”等等。
比如这篇文章的解释:http://blog.sina.com.cn/s/blog_3eaec8ff010009ge.html
但是这个明显就不适用,另外一篇倒是给了一个相对来说靠谱的答案:https://blog.csdn.net/networkangle/article/details/52549758?tdsourcetag=s_pcqq_aiomsg 里面给出了这么一段话:
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));
里面这个SO_BINDTODEVICE上网找了一下,好像是可以绕过路由表查找,但是这是Linux系统下适用的,我的代码是windows系统c++语言,后来就找到了它的替代产物:SO_DONTROUTE,我以为找到了解决方案就写了以下代码:
bUsed = TRUE;
if(setsockopt(m_hSocket,SOL_SOCKET,SO_DONTROUTE,(char*)&bUsed,sizeof(BOOL)) == SOCKET_ERROR)
{
closesocket(m_hSocket);
g_pLogWriter->WriteNMLog(logLevelError,L"setsockopt SO_DONTROUTE Failed");
return S_FALSE;
}
一测试,还是没用。
上网找了一下资料,在这篇文章https://blog.csdn.net/sherlockhua/article/details/5365873里发现了这个结论:
所以就还是不行,看起来只能修改路由了。这段文字也验证了这个猜想。
那么就只能改路由了。然后我就发现了最关键的解决方案:静态路由方案添加静态路由解决双网卡问题
由于这篇文章太重要了,我就把它的内容摘抄出来:
为了保证某些关键应用系统的可靠性,其网络子系统往往采用双网结构,系统中每一台服务器和工作站都安装两块网卡,在两个并行的网络里发送和接受数据。为了保证两块网卡都发送数据包,需要在计算机里添加静态路由。
如果两款网卡上都设置了默认网关,系统不会报错。但实际上同一时刻只能有一个默认网关有效。因此,应该在一块网卡上设置默认网关,另一块网卡不设默认网关,而是在路由表里添加一条静态路由。
客户端ipconfig信息:
可以看到要使用的IP地址10.0.0.2以太网名字是em4, 然后在网络共享中心就可以看到全部以太网,对应找到真实名字。从这张表也可以看出的确10.0.0.2没有设置默认网关。
输入dos命令 route print 打印出现在机器上所有的路由表以及网卡信息:
可以看到我们要的这块网卡编号是14. 以及当前所有路由表。
然后我们输入dos命令:route add -p 10.0.0.1 mask 255.255.255.255 172.16.148.1 metric 3 if 14
这条命令代表发往10.0.0.1的数据包都由14号网卡经过网关172.16.148.1进行发送,跃点数为3.
这样就加上去了。在运行route print 可以看到多了一条记录:
同样的,我们在服务端也按照相应的流程输入一条静态路由表:
route add -p 10.0.0.2 mask 255.255.255.255 172.16.148.1 metric 3 if 12
这样再一运行,就会发现已经就可以生效了!
//*****************************************************知识分割线,以及网友成功运行案例*************************************************//
接下来补充一点知识:
先ping一下看通不通,然后route print一下查看。
子网掩码设置成255.255.255.255,代表在路由方面是全匹配,只能匹配一个ip地址。
网关的作用:网关是指数据从你接口出去先走哪里比如就是你要出门,先要走你家大门一样,有些家庭不止一个大门的,所以要 指定。数据应该到网关再由网关转发出去,但是一个网络里,不一定只有一个网关,比如有些人的网络, 192.168.1.1是电信网关,192.168.1.2是移动网关,所以是有多网关的情况存在的。
在windows下怎么增加、删除、修改一条路由
然后这里我还想记录几个网友成功运行的案例,以备不时之需。
案例一:双网卡下添加静态路由
系统平台:WIN8.1
情况描述:电脑上安装了2个网卡,一个连接外网(自动分配IP,路由地址为192.168.0.1),
一个连接单位内网(网卡静态IP为10.37.130.130,网关10.37.130.129,子网掩码255.255.255.252,内网网段10.37.0.0)
任务目标:按需访问内外网
操作方法:用管理员权限打开CMD,
1、删除默认路由:输入 route delete 0.0.0.0 ( 0.0.0.0是指所有地址)
2、添加静态路由
2-1,添加内网静态路由:route add 10.37.0.0 mask 255.255.0.0 10.37.132.129 -p
注:它表示访问10.37.0.0网段的所有数据都要经过网关10.37.132.129,-p表示Persistent(持久有效的意思,重启后依然生效)
2-2,添加外网静态路由:route add 0.0.0.0 mask 0.0.0.0 192.168.0.1 -p
注:它表示访问0.0.0.0网址和0.0.0.0网段,即任意网址任意网段,访问经过外网网关192.168.0.1。
3、设置完成后,输入route print 看一下路由表是否添加成功,再ping内外网的网址测试下是否有效。
经验教训:
我试验过好几次都失败,能上外网但上不了内网。检查后发现在2-1步骤中把目标地址的子网掩码范围设置的太小,我设置成了255.255.255.0,忽视了内网中可能存在其他地址设置。如果想范围更大一些的话,还可以把子网掩码改成255.0.0.0,目标地址改成10.0.0.0
——————————————————————————————————————————
知识点:
ROUTE路由命令简单解说
ROUTE命令格式如下:
ROUTE [-f] [-p] [command [destination] [MASK netmask] [gateway] [METRIC metric] [IF interface]
其中 –f 参数用于清除路由表,-p参数用于永久保留某条路由(即在系统重启时不会丢失路由)。
Command主要有PRINT(打印)、ADD(添加)、DELETE(删除)、CHANGE(修改)共4个命令。
Destination代表所要达到的目标IP地址。
MASK是子网掩码的关键字。Netmask代表具体的子网掩码,如果不加说明,默认是255.255.255.255(单机IP地址),因此键入掩码时候要特别小心,要确认添加的是某个IP地址还是IP网段。如果代表全部出口子网掩码可用0.0.0.0。
Gateway代表出口网关。
其他interface和metric分别代表特殊路由的接口数目和到达目标地址的代价,一般可不予理会。
案例二:小结解决双网卡网关问题(route add -p) ---关于静态路由
以及网友在贴吧上发的帖子的解决方案:http://bbs.51cto.com/thread-1549709-1-1.html
其实不用添加网卡的。
以前在医院上班,有电脑需要同时用到区医保、市医保、新农合、外网,
直接给4个IP ,添加静态路由就可以了。