You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

虚拟机中C程序与C# WinForm通信时出现连接被主动拒绝错误

问题分析与解决方案

核心问题

你遇到的「目标机器主动拒绝连接」错误,本质是TCP通信角色混淆:你的C#代码是客户端,虚拟机里的C代码也写的是客户端逻辑(调用connect发起连接),没有任何一端作为服务器监听端口,自然无法建立连接。此外,虚拟机里的C代码还存在语法和变量拼写错误,导致编译或运行异常。

修复步骤

1. 明确通信角色

选择一端作为服务器(监听端口等待连接),另一端作为客户端(主动发起连接)。推荐让虚拟机里的C程序做服务器,C#程序做客户端:

  • 虚拟机C服务器监听8888端口
  • C#客户端连接虚拟机IP(192.168.80.128)和8888端口

2. 修正虚拟机C代码(改为服务器模式)

修复语法错误,实现标准TCP服务器逻辑:

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

#define PORT 8888

void handle_client(int client_socket) {
    char buffer[256];
    ssize_t bytes_read;

    // 读取客户端发送的消息
    bytes_read = read(client_socket, buffer, sizeof(buffer) - 1);
    if (bytes_read > 0) {
        buffer[bytes_read] = '\0'; // 确保字符串终止
        printf("Message from App: %s\n", buffer);
        
        // 发送响应给客户端
        const char* response = "OK!";
        write(client_socket, response, strlen(response));
    }

    close(client_socket);
}

int main() {
    int server_fd, client_socket;
    struct sockaddr_in address;
    int opt = 1;
    socklen_t addrlen = sizeof(address);

    // 创建套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 设置套接字选项,允许端口复用
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("setsockopt failed");
        exit(EXIT_FAILURE);
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡接口
    address.sin_port = htons(PORT);

    // 绑定套接字到指定端口
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 开始监听连接,最大等待队列3个
    if (listen(server_fd, 3) < 0) {
        perror("listen failed");
        exit(EXIT_FAILURE);
    }

    printf("Server is listening on port %d...\n", PORT);

    // 循环接受客户端连接
    while ((client_socket = accept(server_fd, (struct sockaddr *)&address, &addrlen)) >= 0) {
        printf("New client connected from %s:%d\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));
        handle_client(client_socket);
    }

    if (client_socket < 0) {
        perror("accept failed");
        exit(EXIT_FAILURE);
    }

    close(server_fd);
    return 0;
}

3. 保留C#客户端代码(仅确认IP正确)

你的C#代码逻辑基本正确,确保调用ConnectClient时传入的IP是虚拟机的实际IP(192.168.80.128):

private void ConnectClient(string server, string message)
{
    try
    {
        Int32 port = 8888;
        TcpClient client = new TcpClient(server, port);

        Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
        NetworkStream stream = client.GetStream();

        // 发送消息
        stream.Write(data, 0, data.Length);
        Console.WriteLine("Sent: {0}", message);

        // 接收响应
        data = new Byte[256];
        String responseData = String.Empty;
        Int32 bytes = stream.Read(data, 0, data.Length);
        responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
        Console.WriteLine("Received: {0}", responseData);

        stream.Close();
        client.Close();
    }
    catch (ArgumentNullException e)
    {
        Console.WriteLine("ArgumentNullException: {0}", e);
    }
    catch (SocketException e)
    {
        Console.WriteLine("SocketException: {0}", e);
    }

    Console.WriteLine("\n Press Enter to continue...");
    Console.Read();
}

private void ConnectBTN_Click(object sender, EventArgs e)
{
    ConnectClient("192.168.80.128", "test");
}

4. 网络连通性验证

  • 在主机上ping虚拟机IP(192.168.80.128),确保能互通
  • 确认VMware网络模式:若用NAT,需保证主机VMnet8网卡和虚拟机IP在同一网段;若用桥接,需和主机在同一局域网段
  • 再次确认两边防火墙已关闭(包括虚拟机系统内的防火墙)

5. 运行顺序

  1. 先启动虚拟机里的C服务器程序,看到Server is listening on port 8888...提示
  2. 再运行C# WinForms程序,点击连接按钮,即可完成通信

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:05:25