完美解决主机与虚拟机相互通信,相互ping等问题

  笔者最近在学习使用linux时,使用到了vm virtue box的虚拟机服务来简单的安装linux,但是在使用的时候发现了一个严重的问题:虚拟机可以ping通主机,主机却无法ping通虚拟机。

  在通过对防火墙的设置,以及改变虚拟机网络连接方式均无果后,笔者找到了一个可以说是比较万能的方法。

  首先,让我们浅浅了解一下虚拟机不同的网络连接方式以及其背后的潜规则。

  

  如图,在大部分虚拟机默认的NAT转换是能实现虚拟机向主机的ping的(如果你主机防火墙没问题),但是,在主机ping虚拟机中,它却束手无策了。眼尖的小伙伴们很快便可以发现,这BridgedAdapter不全是√√√吗?确实,笔者在见到这一连接方式时便大松一口气,草草将连接方式替换为了桥接网卡,但结果却不尽人意。

  我甚至失去了连接互联网的能力。

  但是解决的方法并非高深莫及,nat有网,不能ping通,桥接网卡没网,在有ipv4地址后可以ping通,缝合一下,问题就解决了。

  1:网卡一选择桥接网卡,网卡2选择nat转换

2:找到etc/network 下的interfaces 添加正确的ip地址(与你主机同一子网)

复制内容:

source /etc/network/interfaces.d/*

auto enp0s3(使用ifconfig找到你桥接网卡的网络名称 我的是enp0s3 (括号里的自己删掉 我是提醒你) )

iface enp0s3 inet static

address 10.199.40.3

netmask 255.255.240.0

getway 10.199.47.254

这是我win10 ipconfig的结果

两个对照着照葫芦画瓢复制修改就行。

3.shutdown -r now 重启观察效果

  ok,按部就班了!既然可以双向通信了,那我们还可以试试socket来进行通信玩玩。

win10客户端代码:

#include <stdio.h>
#include <Windows.h>
#pragma warning(disable:4996) 
#pragma comment(lib, "ws2_32.lib")
#define Port 5000
#define IP_ADDRESS "10.199.40.3"

int main(int argc, char* argv[]) // argc是命令行总的参数个数
{

    WSADATA s; // 用来储存调用AfxSocketInit全局函数返回的Windows Sockets初始化信息
    SOCKET ClientSocket;
    struct sockaddr_in ClientAddr; // 一个sockaddr_in型的结构体对象
    int ret = 0;
    char SendBuffer[MAX_PATH];   // Windows的MAX_PATH默认是260

    // 初始化Windows Socket
    // WSAStartup函数对Winsock服务的初始化
    if (WSAStartup(MAKEWORD(2, 2), &s) != 0) // 通过连接两个给定的无符号参数,首个参数为低字节
    {
        printf("Init Windows Socket Failed! Error: %d\n", GetLastError());
        getchar();
        return -1;
    }

    while (1)
    {
        // 创建一个套接口
        // 如果这样一个套接口用connect()与一个指定端口连接
        // 则可用send()和recv()与该端口进行数据报的发送与接收
        // 当会话结束后,调用closesocket()
        ClientSocket = socket(AF_INET, // 只支持ARPA Internet地址格式
            SOCK_STREAM, // 新套接口的类型描述
            IPPROTO_TCP); // 套接口所用的协议
        if (ClientSocket == INVALID_SOCKET)
        {
            printf("Create Socket Failed! Error: %d\n", GetLastError());
            getchar();
            return -1;
        }

        ClientAddr.sin_family = AF_INET;
        ClientAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS); // 定义IP地址
        ClientAddr.sin_port = htons(Port); // 将主机的无符号短整形数转换成网络字节顺序
        memset(ClientAddr.sin_zero, 0X00, 8); // 函数通常为新申请的内存做初始化工作

        // 连接Socket
        ret = connect(ClientSocket,
            (struct sockaddr*)&ClientAddr,
            sizeof(ClientAddr));
        if (ret == SOCKET_ERROR)
        {
            printf("Socket Connect Failed! Error:%d\n", GetLastError());
            getchar();
            return -1;
        }
        else
        {
            printf("Socket Connect Succeed!");
        }

        printf("Input Data: ");
        while (1)
        {
            scanf("%s", &SendBuffer);

            // 发送数据至服务器
            ret = send(ClientSocket,
                SendBuffer,
                (int)strlen(SendBuffer), // 返回发送缓冲区数据长度
                0);

            if (ret == SOCKET_ERROR)
            {
                printf("Send Information Failed! Error:%d\n", GetLastError());
                getchar();
                break;
            }

            break;
        }

        // 关闭socket
        closesocket(ClientSocket);
        if (SendBuffer[0] == 'q') // 设定输入第一个字符为q时退出
        {
            printf("Quit!\n");
            break;
        }

    }
    WSACleanup();
    getchar();
    return 0;
}

ubuntu服务端代码:

#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>

#define SERVER_PORT 5000
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 10

int main() // (int argc, char* argv[])
{
    struct sockaddr_in server_addr;
    int server_socket;
    int opt = 1;

    bzero(&server_addr, sizeof(server_addr)); // 置字节字符串前n个字节为0,包括'\0'
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY); // 转小端,INADDR_ANY就是指定地址为0.0.0.0的地址
    server_addr.sin_port = htons(SERVER_PORT);  

    // 创建一个Socket
    server_socket = socket(PF_INET, SOCK_STREAM, 0);

    if (server_socket < 0)
    {
        printf("Create Socket Failed!\n");
        exit(1);
    }


    // bind a socket
    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    if(bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
    {
        printf("Server Bind Port: %d Failed!\n", SERVER_PORT);
        exit(1);
    }

    // 监听Socket
    if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
    {
        printf("Server Listen Failed!\n");
        exit(1);
    }      

    while(1)
    {

        struct sockaddr_in client_addr;
        int client_socket;
        socklen_t length;
        char Buffer[BUFFER_SIZE];

        // 连接客户端Socket
        length = sizeof(client_addr);
        client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
        if (client_socket < 0)
        {
            printf("Server Accept Failed!\n");
            break;
        }

        // 从客户端接收数据
        while(1)
        {
            bzero(Buffer, BUFFER_SIZE);
            length = recv(client_socket, Buffer, BUFFER_SIZE, 0);

            if (length < 0)
            {
                printf("Server Recieve Data Failed!\n");
                break;
            }           

            if ('q' == Buffer[0])
            {
                printf("Quit!\n");
                break;
            }

            printf("%s\n", Buffer);
            break;

        }

        close(client_socket);
    }

    close(server_socket);
    return 0;
}

运行结果:

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
这个问题可能有多种原因导致主机虚拟无法互相ping通。下面是一些可能的解决方案: 1. 网络配置问题:确保主机虚拟的网络配置正确。检查主机虚拟的IP地址、子网掩码、网关等网络设置,确保它们在同一子网。 2. 防火墙设置:检查主机虚拟上的防火墙设置,确保它们允许ICMP流量通过。如果防火墙阻止了ping请求,可以尝试禁用防火墙或者修改防火墙规则。 3. 虚拟网络配置:如果使用虚拟化软件如VMware或VirtualBox,确保虚拟网络适配器设置正确。检查虚拟网络适配器的模式(桥接模式、NAT模式等)是否正确配置,以便主机虚拟能够相互通信。 4. 路由器设置:如果主机虚拟分别连接到不同的路由器或子网,确保路由器之间进行正确的路由配置。检查路由器的路由表和网络设置,确保主机虚拟之间的路由是正确的。 5. 虚拟化软件设置:如果使用虚拟化软件创建虚拟,检查虚拟化软件的网络设置。确保虚拟网络适配器的连接方式正确,例如NAT、桥接等。 6. 网络故障排除:如果以上解决方案都没有解决问题,可以使用网络故障排除工具(如tracert、tcpdump等)来进一步分析网络连接问题,以确定具体原因。 请根据具体情况逐一尝试这些解决方案,希望能帮助您解决主机虚拟ping不通的问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值