虚拟机中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. 运行顺序
- 先启动虚拟机里的C服务器程序,看到
Server is listening on port 8888...提示 - 再运行C# WinForms程序,点击连接按钮,即可完成通信
内容的提问来源于stack exchange,提问作者oalwix
相关产品推荐
相关产品推荐

