You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过Socket连接Windows Java客户端与Linux虚拟机C++服务器?

解决Windows客户端连接Linux NAT虚拟机服务器的IP问题

首先得明确:你的Linux虚拟机用的是NAT网络模式,它的10.0.2.15是虚拟机在虚拟化软件专属的NAT虚拟子网里的内部地址——这个地址没法直接被你的Windows主机访问,因为Windows主机在192.168.1.x网段,和虚拟机的10.0.2.x网段是完全隔离的,这就是你连不上的核心原因。

下面给你两种靠谱的解决办法,按需选就行:

方法一:配置端口转发(推荐,保留NAT模式的网络安全性)

NAT模式下,虚拟机默认是通过Windows主机的网络向外访问,反过来要让主机访问虚拟机,得给虚拟化软件加个端口转发规则,把主机的某个端口映射到虚拟机的服务器端口(你的是1236)。这里以VMware为例,VirtualBox操作逻辑类似:

  1. 打开你的Linux虚拟机对应的VMware界面,点击「编辑虚拟机设置」
  2. 切换到「网络适配器」选项卡,点击右侧的「NAT设置」按钮
  3. 在弹出的窗口里点击「添加」,设置转发规则:
    • 主机端口:选一个没被占用的端口,比如12360(只要不是系统常用端口都可以)
    • 类型:选TCP(因为你的是TCP socket连接)
    • 虚拟机IP地址:填虚拟机的10.0.2.15
    • 虚拟机端口:填你的服务器监听的1236
  4. 保存设置后,重启虚拟机的网络服务(或者直接重启虚拟机)

之后你的Java客户端代码改成连接Windows主机的本地IP或者局域网IP就行:

// 用localhost也可以,因为是连接本机的转发端口
socket = new Socket("127.0.0.1", 12360);
// 或者用Windows的局域网IP 192.168.1.3
socket = new Socket("192.168.1.3", 12360);

方法二:切换到桥接模式(更直接的局域网访问)

桥接模式会让虚拟机直接接入和Windows主机同一个局域网(也就是192.168.1.x网段),这样两者就能像普通局域网设备一样互相访问:

  1. 先关闭你的Linux虚拟机,然后打开「编辑虚拟机设置」
  2. 切换到「网络适配器」,把网络连接方式改成「桥接模式」,记得勾选「复制物理网络连接状态」
  3. 启动虚拟机,执行dhclient enp0s3命令重新获取IP(或者重启虚拟机)
  4. 再跑一遍ifconfig,你会看到虚拟机的IP变成192.168.1.x网段的地址了(比如192.168.1.105

这时你的Java客户端直接用这个新IP连接服务器就行:

socket = new Socket("192.168.1.xxx", 1236);

额外要注意的细节

  • 不管用哪种方法,都得确保Linux虚拟机的防火墙允许1236端口的TCP连接:
    # 如果是iptables防火墙
    sudo iptables -A INPUT -p tcp --dport 1236 -j ACCEPT
    # 如果是firewalld防火墙
    sudo firewall-cmd --add-port=1236/tcp --permanent
    sudo firewall-cmd --reload
    
  • 确认你的C++服务器是监听在0.0.0.0而不是127.0.0.1——如果服务器只监听localhost,哪怕IP对了也没法从外部访问,服务器的监听代码要设置成监听所有网卡:
    // 示例代码片段:确保监听所有网卡的1236端口
    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(1236);
    // 关键:用INADDR_ANY表示监听所有可用网卡
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    

内容的提问来源于stack exchange,提问作者Piotter

火山引擎 最新活动