C#程序无法连接MySQL数据库:连接被主动拒绝问题排查
解决C#连接MySQL时出现“SocketException: 目标机器主动拒绝连接127.0.0.1:3306”的问题
问题描述
我在C#程序中尝试用MySQL作为数据存储介质,用于导出数据供用户查看,初始化连接的代码如下:
string MyConnection2 = "server=localhost;database=leaderboard;user=root;password=root"; MySqlConnection MyConn2 = new MySqlConnection(MyConnection2); string Query = "insert into leaderboard.leaderboard(Name,Score,Lives, Time) values('" + nameText.Text + "','" + "','" + scoreLabel.Text + "','" + livesText.Text + "','" + timeText.Text + "');"; MySqlCommand MyCommand2 = new MySqlCommand(Query, MyConn2); MySqlDataReader MyReader2; MyConn2.Open(); MyReader2 = MyCommand2.ExecuteReader(); if (MyConn2.State == ConnectionState.Open) { MessageBox.Show("Connection established!"); } else { MessageBox.Show("No connection established"); }
但调试跳转到对应窗体时出现错误:SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:3306
问题成因分析
这个错误本质是你的C#程序无法通过TCP/IP连接到本地的MySQL服务,常见原因有以下几点:
- MySQL服务未启动:3306是MySQL默认监听端口,如果服务没运行,自然会拒绝所有连接请求
- 3306端口被占用:其他程序(比如另一个数据库服务、网络工具)占用了3306端口,导致MySQL无法正常监听
- MySQL配置禁用了TCP/IP连接:比如配置了
skip-networking参数,或者bind-address设置为非本地IP,导致本地无法连接 - 防火墙拦截:本地防火墙阻止了C#程序访问3306端口
- 连接字符串细节问题:比如
localhost解析异常,或者未明确指定端口号导致连接到错误端口
分步解决方法
检查并启动MySQL服务
- Windows系统:按下
Win+R输入services.msc打开服务管理器,找到名称类似MySQL80(取决于你的MySQL版本)的服务,查看状态是否为“正在运行”。如果未运行,右键选择“启动”,还可以设置为“自动”启动避免后续重复问题。 - Linux/macOS系统:打开终端,执行
sudo systemctl status mysql查看服务状态,未运行则执行sudo systemctl start mysql启动服务。
- Windows系统:按下
验证3306端口是否被占用
- Windows系统:打开命令提示符,输入
netstat -ano | findstr :3306。如果有输出,查看对应的PID,通过任务管理器找到该PID对应的程序:如果不是MySQL,关闭该程序;如果需要保留,可以修改MySQL的监听端口(在my.ini配置文件中修改port参数,重启服务生效)。 - Linux/macOS系统:执行
sudo lsof -i :3306或netstat -tulpn | grep 3306检查端口占用,处理方式和Windows类似。
- Windows系统:打开命令提示符,输入
检查MySQL的TCP/IP连接配置
- 找到MySQL的配置文件(Windows通常在
C:\ProgramData\MySQL\MySQL Server X.X\my.ini,Linux/macOS多在/etc/mysql/my.cnf) - 确保
bind-address参数设置为127.0.0.1(仅允许本地连接)或0.0.0.0(允许所有IP连接),如果该参数被注释也可以正常使用 - 检查是否存在
skip-networking参数,如果有则注释掉(该参数会禁用TCP/IP连接) - 修改配置后必须重启MySQL服务才能生效
- 找到MySQL的配置文件(Windows通常在
调整防火墙设置
- Windows防火墙:打开“Windows Defender防火墙”→“高级设置”,添加一条入站规则,允许TCP协议的3306端口通过;同时确保你的C#程序被允许通过防火墙访问网络。
- Linux防火墙(以ufw为例):执行
sudo ufw allow 3306/tcp允许端口访问,再执行sudo ufw reload使规则生效。
优化连接字符串
- 明确指定端口号,避免解析问题:
server=127.0.0.1;port=3306;database=leaderboard;user=root;password=root - 用
127.0.0.1代替localhost,有些系统的localhost解析可能存在异常,直接使用本地IP更可靠
- 明确指定端口号,避免解析问题:
额外建议:修复你的SQL注入风险
你的代码中直接用字符串拼接生成SQL语句,存在严重的SQL注入风险,建议改用参数化查询,同时插入操作应该用ExecuteNonQuery()而不是ExecuteReader()(后者用于查询返回结果集),修改后的代码示例:
string MyConnection2 = "server=127.0.0.1;port=3306;database=leaderboard;user=root;password=root"; using (MySqlConnection MyConn2 = new MySqlConnection(MyConnection2)) { string Query = "insert into leaderboard.leaderboard(Name, Score, Lives, Time) values(@Name, @Score, @Lives, @Time);"; using (MySqlCommand MyCommand2 = new MySqlCommand(Query, MyConn2)) { // 添加参数,避免SQL注入 MyCommand2.Parameters.AddWithValue("@Name", nameText.Text); MyCommand2.Parameters.AddWithValue("@Score", scoreLabel.Text); MyCommand2.Parameters.AddWithValue("@Lives", livesText.Text); MyCommand2.Parameters.AddWithValue("@Time", timeText.Text); try { MyConn2.Open(); int rowsAffected = MyCommand2.ExecuteNonQuery(); MessageBox.Show("数据插入成功,连接已建立!"); } catch (Exception ex) { MessageBox.Show($"连接或插入失败:{ex.Message}"); } } }
使用using语句还能自动释放连接资源,避免连接泄漏问题。
内容的提问来源于stack exchange,提问作者Steve Darrenson
相关产品推荐
相关产品推荐

