繁体   English   中英

服务器TCP socket只接收一个网络接口linux的数据

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM