![](/img/trans.png)
[英]Linux C Sockets - Binded socket receives packets from another interface?
[英]Server TCP socket only receives data from one network interface linux
我使用的是服务器TCP socket代码写在C中,这里会有多个客户端连接到服务器通过以下方式发送数据:
main()
{
struct sockaddr_in myAddress;
int ret = 1;
int optVal = 1;
int sockFd;
printf("NEW FW UPDATE DOWNLOADER starts");
// Create the socket
sockFd = socket (AF_INET, SOCK_STREAM, 0);
//sockFd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
const char *opt = "eth0";
const int len = strnlen(opt, IFNAMSIZ);
printf("interface %s, len %d", opt, len);
if(len == IFNAMSIZ){
printf("interface name too long");
return;
}
if (sockFd < 0)
{
printf("creating socket failed: %m");
return;
}
// set socket option
// we use SO_REUSEADDR to be able to accept several clients without closing the socket
ret = setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(optVal));
if (ret)
{
printf("error setting socket option %m");
close(sockFd);
return;
}
/*
ret = setsockopt(sockFd, SOL_SOCKET, SO_BINDTODEVICE, (void *)opt, len);
if (ret)
{
printf("error setting socket option %m");
close(sockFd);
return;
}
*/
memset(&myAddress, 0, sizeof(myAddress));
myAddress.sin_port = htons(FWUPDATE_SERVER_PORT);
myAddress.sin_family = AF_INET;
myAddress.sin_addr.s_addr = htonl(INADDR_ANY);
// Bind server - socket
ret = bind(sockFd, (struct sockaddr_in *)&myAddress, sizeof(myAddress));
if (ret)
{
printf("bind failed %m");
close(sockFd);
return;
}
// Listen on the socket
ret = listen(sockFd, 1);
if (ret)
{
printf("listen error: %m");
close(sockFd);
return;
}
printf("Listening to socket now..");
}
这个 function 设置为一个处理程序,每次触发 POLLIN 时都会调用
static void SocketEventHandler
(
int fd
)
{
struct sockaddr_in clientAddress;
//le_result_t result;
int connFd;
socklen_t addressLen = sizeof(clientAddress);
LE_INFO("waiting connection ...");
connFd = accept(fd, (struct sockaddr *)&clientAddress, &addressLen);
if (connFd == -1)
{
LE_ERROR("accept error: %m");
}
else
{
LE_INFO("Connected ...");
return;
}
这些也是我在这个 linux(busybox)操作系统上的网络接口:
bridge0 Link encap:Ethernet HWaddr AE:F6:C9:AF:4C:5C
inet addr:192.168.225.1 Bcast:192.168.225.255 Mask:255.255.255.0
inet6 addr: fe80::acf6:c9ff:feac:4959%1331437436/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:76 (76.0 B)
ecm0 Link encap:Ethernet HWaddr 1A:C3:CC:A3:EA:ED
inet addr:192.168.2.2 Bcast:192.168.2.255 Mask:255.255.255.0
inet6 addr: fe80::18c3:ccff:fea3:eaed%1331437436/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1772 errors:0 dropped:5 overruns:0 frame:0
TX packets:821 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:166139 (162.2 KiB) TX bytes:143712 (140.3 KiB)
eth0 Link encap:Ethernet HWaddr 00:14:3E:9D:BA:E7
inet addr:192.168.0.31 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::214:3eff:fe9d:bae7%1331437436/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3707 errors:0 dropped:0 overruns:0 frame:0
TX packets:91 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:515771 (503.6 KiB) TX bytes:4974 (4.8 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1%1331437436/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:3 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:244 (244.0 B) TX bytes:244 (244.0 B)
rmnet0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING MTU:2000 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
看来我只能从 ecm0 接口接收数据,所以如果我尝试:telnet 192.168.2.2 9000 而当我尝试连接到 eth0 时它将不起作用:telnet 192.168.0.31 9000
我已经检查了路由和映射,但是套接字应该从任何接口(据我所知)绑定到任何 IP 并且 iproutes 应该适用于所有接口,所以如果我可以到达 ecm0 上的端口,我应该能够到达eth0 上的相同端口。
我可以 ping 两个 IP 192.168.2.2 和 192.168.0.31,但我只能通过 192.168.2.2 连接到 TCP 服务器套接字。
这是我明显想念的东西吗?
我使用的是服务器TCP socket代码写在C中,这里会有多个客户端连接到服务器通过以下方式发送数据:
main()
{
struct sockaddr_in myAddress;
int ret = 1;
int optVal = 1;
int sockFd;
printf("NEW FW UPDATE DOWNLOADER starts");
// Create the socket
sockFd = socket (AF_INET, SOCK_STREAM, 0);
//sockFd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
const char *opt = "eth0";
const int len = strnlen(opt, IFNAMSIZ);
printf("interface %s, len %d", opt, len);
if(len == IFNAMSIZ){
printf("interface name too long");
return;
}
if (sockFd < 0)
{
printf("creating socket failed: %m");
return;
}
// set socket option
// we use SO_REUSEADDR to be able to accept several clients without closing the socket
ret = setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(optVal));
if (ret)
{
printf("error setting socket option %m");
close(sockFd);
return;
}
/*
ret = setsockopt(sockFd, SOL_SOCKET, SO_BINDTODEVICE, (void *)opt, len);
if (ret)
{
printf("error setting socket option %m");
close(sockFd);
return;
}
*/
memset(&myAddress, 0, sizeof(myAddress));
myAddress.sin_port = htons(FWUPDATE_SERVER_PORT);
myAddress.sin_family = AF_INET;
myAddress.sin_addr.s_addr = htonl(INADDR_ANY);
// Bind server - socket
ret = bind(sockFd, (struct sockaddr_in *)&myAddress, sizeof(myAddress));
if (ret)
{
printf("bind failed %m");
close(sockFd);
return;
}
// Listen on the socket
ret = listen(sockFd, 1);
if (ret)
{
printf("listen error: %m");
close(sockFd);
return;
}
printf("Listening to socket now..");
}
这个 function 设置为一个处理程序,每次触发 POLLIN 时都会调用
static void SocketEventHandler
(
int fd
)
{
struct sockaddr_in clientAddress;
//le_result_t result;
int connFd;
socklen_t addressLen = sizeof(clientAddress);
LE_INFO("waiting connection ...");
connFd = accept(fd, (struct sockaddr *)&clientAddress, &addressLen);
if (connFd == -1)
{
LE_ERROR("accept error: %m");
}
else
{
LE_INFO("Connected ...");
return;
}
这些也是我在这个 linux(busybox)操作系统上的网络接口:
bridge0 Link encap:Ethernet HWaddr AE:F6:C9:AF:4C:5C
inet addr:192.168.225.1 Bcast:192.168.225.255 Mask:255.255.255.0
inet6 addr: fe80::acf6:c9ff:feac:4959%1331437436/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:76 (76.0 B)
ecm0 Link encap:Ethernet HWaddr 1A:C3:CC:A3:EA:ED
inet addr:192.168.2.2 Bcast:192.168.2.255 Mask:255.255.255.0
inet6 addr: fe80::18c3:ccff:fea3:eaed%1331437436/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1772 errors:0 dropped:5 overruns:0 frame:0
TX packets:821 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:166139 (162.2 KiB) TX bytes:143712 (140.3 KiB)
eth0 Link encap:Ethernet HWaddr 00:14:3E:9D:BA:E7
inet addr:192.168.0.31 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::214:3eff:fe9d:bae7%1331437436/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3707 errors:0 dropped:0 overruns:0 frame:0
TX packets:91 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:515771 (503.6 KiB) TX bytes:4974 (4.8 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1%1331437436/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:3 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:244 (244.0 B) TX bytes:244 (244.0 B)
rmnet0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING MTU:2000 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
看来我只能从 ecm0 接口接收数据,所以如果我尝试:telnet 192.168.2.2 9000 而当我尝试连接到 eth0 时它将不起作用:telnet 192.168.0.31 9000
我已经检查了路由和映射,但是套接字应该从任何接口(据我所知)绑定到任何 IP 并且 iproutes 应该适用于所有接口,所以如果我可以到达 ecm0 上的端口,我应该能够到达eth0 上的相同端口。
我可以 ping 两个 IP 192.168.2.2 和 192.168.0.31,但我只能通过 192.168.2.2 连接到 TCP 服务器套接字。
这是我明显想念的东西吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.