gpt4 book ai didi

c - 绑定(bind)到两个本地 IP 失败

转载 作者:可可西里 更新时间:2023-11-01 02:52:09 25 4
gpt4 key购买 nike

我有两个无线适配器,一个 USB 适配器和一个内置在我的笔记本电脑中。

我希望能够使用这两个连接。因此,在玩具示例中,我将两个不同的套接字绑定(bind)到两个不同的 IP 地址和端口号,并在每个套接字上调用连接。

但是,当我在 wireshark 中检查我的网络流量时...我只看到来自一个 ip 的流量!?事实上,尽管我明确绑定(bind)了每个套接字,但我看到了从一个 IP 地址进行连接的两个调用。

这是我使用的代码:

请注意,我还使用了非阻塞套接字和选择。我拥有的代码已经过验证可用于一个互联网连接。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <net/if.h>
#include <sys/ioctl.h>


int main () {

const char * destIp = "213.112.225.102";

const char * ip1 = "192.168.43.1";//"172.31.55.111";//"198.228.228.28";
int portNumber1 = 55555;
int sockFd1 = -1;

const char * ip2 = "192.168.1.1";//"98.249.5.16";
int portNumber2 = 7777;
int sockFd2 = -1;

struct sockaddr_in serverAddress;
serverAddress.sin_addr.s_addr = inet_pton(AF_INET, "213.112.225.102", &(serverAddress.sin_addr));
serverAddress.sin_port = htons(6985);

///////////////////////////////////////////
struct sockaddr * saddr;
struct addrinfo hints, * ai, * it;
char strportnum[] = "6985";
memset(&hints, '\0', sizeof(hints));
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_socktype = SOCK_STREAM;

getaddrinfo(destIp, strportnum, &hints, &ai);

saddr = ai->ai_addr;
saddr->sa_family = AF_INET;

it = ai;
///////////////////////////////////////////////
//char * opt;
int res;
long arg;
fd_set myset;
struct timeval tv;
int valopt;
socklen_t lon;
struct sockaddr_in clientAddress;
struct sockaddr_in clientAddress2;

printf("it fam == ||%d||, AF_INET == ||%d||\n", it->ai_family, AF_INET);

printf("ATTEMPTING SOCKET 1!\n");
//IP 1 CONNECTION----------------------------------------------------------------------------------//
if ((sockFd1 = socket(it->ai_family, it->ai_socktype, it->ai_protocol)) != -1) {


system("route add -net 213.112.225.102 netmask 255.255.255.255 gw 192.168.43.1 dev wlp10s0");

struct ifreq interface1;
memset(&interface1, 0, sizeof(interface1));
strncpy(interface1.ifr_ifrn.ifrn_name, "wlp10s0", IFNAMSIZ);

if (setsockopt(sockFd1, SOL_SOCKET, SO_BINDTODEVICE, &interface1, sizeof(interface1)) < 0) {
printf("error in set sock opt 1... errno == %d strerror == (%s)\n", errno, strerror(errno));

close(sockFd1); // Error
return 1;
}


clientAddress.sin_family = AF_INET;
clientAddress.sin_addr.s_addr = inet_pton(AF_INET, ip1, &(clientAddress.sin_addr));
clientAddress.sin_port = htons(portNumber1);
if (bind(sockFd1, (struct sockaddr *) &clientAddress, sizeof(clientAddress)) < 0) {
fprintf(stderr, "Error with bind, errno == %d (%s)\n", errno, strerror(errno));
}



// Set non-blocking
if( (arg = fcntl(sockFd1, F_GETFL, NULL)) < 0) {
fprintf(stderr, "Error fcntl(..., F_GETFL) (%s)\n", strerror(errno));
return 1;
}
arg |= O_NONBLOCK;
if( fcntl(sockFd1, F_SETFL, arg) < 0) {
fprintf(stderr, "Error fcntl(..., F_SETFL) (%s)\n", strerror(errno));
return 1;
}

printf("ATTEMPTING CONNECTION 2!\n");
// Trying to connect with timeout
res = connect(sockFd1, saddr, sizeof(*saddr));
if (res < 0) {

if (errno == EINPROGRESS) {

fprintf(stderr, "EINPROGRESS in connect() - selecting\n");

do {

//Set timeouts
tv.tv_sec = 15;
tv.tv_usec = 0;

FD_ZERO(&myset);
FD_SET(sockFd1, &myset);

res = select(sockFd1 + 1, NULL, &myset, NULL, &tv);

if (res < 0 && errno != EINTR) {
fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
}
else if (res > 0) {

// Socket selected for write
lon = sizeof(int);
if (getsockopt(sockFd1, SOL_SOCKET, SO_ERROR, (void *) &valopt, &lon) < 0) {
fprintf(stderr, "Error in getsockopt() %d - %s\n", errno, strerror(errno));
}

// Check the value returned...
if (valopt) {
fprintf(stderr, "Error in delayed connection() %d - %s\n", valopt, strerror(valopt));
}

break;
}
else {
fprintf(stderr, "Timeout in select() - Cancelling!\n");
break;
}
} while (1);
}
else {
fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
}
}
}



printf("ATTEMPTING SOCKET 2!\n");
//IP 2 CONNECTION----------------------------------------------------------------------------------//
if ((sockFd2 = socket(it->ai_family, it->ai_socktype, it->ai_protocol)) != -1) {

system("route add -net 213.112.225.102 netmask 255.255.255.255 gw 192.168.1.1 dev wlp11s0u1");

struct ifreq interface2;
memset(&interface2, 0, sizeof(interface2));
strncpy(interface2.ifr_ifrn.ifrn_name, "wlp11s0u1", IFNAMSIZ);

if (setsockopt(sockFd2, SOL_SOCKET, SO_BINDTODEVICE, &interface2, sizeof(interface2)) < 0) {
printf("error in set sock opt 2... errno == %d strerror == (%s)\n", errno, strerror(errno));
close(sockFd2); // Error
return 1;
}


clientAddress2.sin_family = AF_INET;
clientAddress2.sin_addr.s_addr = inet_pton(AF_INET, ip2, &(clientAddress.sin_addr));
clientAddress2.sin_port = htons(portNumber2);
if (bind(sockFd2, (struct sockaddr *) &clientAddress2, sizeof(clientAddress2)) < 0) {
fprintf(stderr, "Error with bind (%s)\n", strerror(errno));
}



// Set non-blocking
if( (arg = fcntl(sockFd2, F_GETFL, NULL)) < 0) {
fprintf(stderr, "Error fcntl(..., F_GETFL) (%s)\n", strerror(errno));
return 1;
}
arg |= O_NONBLOCK;
if( fcntl(sockFd2, F_SETFL, arg) < 0) {
fprintf(stderr, "Error fcntl(..., F_SETFL) (%s)\n", strerror(errno));
return 1;
}

printf("ATTEMPTING CONNECTION 2!\n");
// Trying to connect with timeout
res = connect(sockFd2, saddr, sizeof(*saddr));
if (res < 0) {

if (errno == EINPROGRESS) {

fprintf(stderr, "EINPROGRESS in connect() - selecting\n");

do {

//Set timeouts
tv.tv_sec = 15;
tv.tv_usec = 0;

FD_ZERO(&myset);
FD_SET(sockFd2, &myset);

res = select(sockFd2 + 1, NULL, &myset, NULL, &tv);

if (res < 0 && errno != EINTR) {
fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
}
else if (res > 0) {

// Socket selected for write
lon = sizeof(int);
if (getsockopt(sockFd2, SOL_SOCKET, SO_ERROR, (void *) &valopt, &lon) < 0) {
fprintf(stderr, "Error in getsockopt() %d - %s\n", errno, strerror(errno));
}

// Check the value returned...
if (valopt) {
fprintf(stderr, "Error in delayed connection() %d - %s\n", valopt, strerror(valopt));
}

break;
}
else {
fprintf(stderr, "Timeout in select() - Cancelling!\n");
break;
}
} while (1);
}
else {
fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
}
}
}

return 0;
}

/*
ifreq interface;
memset(&interface, 0, sizeof(interface));
strncpy(interface.ifr_ifrn.ifrn_name, "eth1", IFNAMSIZ);

if (setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, &interface, sizeof(interface)) < 0) {
close(sd); // Error
}
*/

那么,为什么绑定(bind)不绑定(bind)!?

编辑:

好的,感谢这篇旧帖子:Multiple Ethernet Interfaces - How to create a separate network and access from C code

我现在采用不同的方法,但我仍然没有利用这两个网络...

最佳答案

我还没有尝试过,只是一个想法。在不查看内核代码的情况下,也许您可​​以欺骗内核,但我不确定它是否会起作用。冒着说错话的风险。

在第一次连接之前,通过“wlp11s0u1”,您通过该接口(interface)将路由设置为“213.112.225.102”。 route add -host 213.112.225.102 gw 1​​92.168.0.1 dev wlp11s0u1(或 GW IP)

然后,在第二次连接之前,通过“wlp10s0”设置路由: route add -host 213.112.225.102 gw 1​​92.168.2.1 dev wlp10s0(或对应网关)

您可以使用 system() 函数来运行“路由”命令。

如果内核在建立连接后不评估路由,它可能会起作用。如果内核为通过连接的套接字发送的每个数据报评估路由,它将无法工作。您可以尝试一个简单的解决方案。


编辑:我也尝试使用 Loose source route 选项,但由于某种原因它对我不起作用,也许我的路由器不允许该 IP 选项。如果你有兴趣,我可以把代码传给你。

其他肯定可行的可能性是您使用数据包套接字,但您必须添加 IP 和 TCP header ,以及管理 ARP、IP 和 TCP 算法。这很有趣。

关于c - 绑定(bind)到两个本地 IP 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20628590/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com