sendto error: Connection refused
时间: 2025-07-05 07:07:31 浏览: 18
在网络编程中,`sendto()` 函数用于发送数据报(如 UDP 协议)到指定的目标地址。当调用 `sendto()` 时出现 **"Connection refused"** 错误,通常意味着目标主机或端口未正确响应或拒绝连接请求。以下是可能导致此错误的常见原因及其排查方法:
### 原因分析
1. **目标服务未运行**
- 如果目标主机上的监听服务没有启动,则无法接收数据包,导致连接被拒绝。
- 确保目标端口上的应用程序正在运行并处于监听状态。
2. **防火墙/安全策略阻止通信**
- 防火墙、SELinux 或其他安全机制可能阻止了数据包到达目标端口。
- 检查目标主机和本地主机的防火墙设置,确认相关端口已开放。
3. **IP 地址或端口号错误**
- 使用了错误的目标 IP 地址或端口号会导致数据包被发送到不存在的服务。
- 核对客户端代码中的 `sockaddr_in` 结构体是否正确设置了目标 IP 和端口。
4. **网络不可达**
- 如果客户端与目标主机之间存在路由问题,也可能导致连接失败。
- 使用 `ping` 或 `traceroute` 检查网络连通性。
5. **UDP 通信中的 ICMP 错误**
- 在使用 UDP 协议时,如果目标主机的端口未监听,可能会返回 ICMP "Port Unreachable" 消息,这在某些系统上表现为 "Connection refused"。
- 这是正常行为,因为 UDP 是无连接协议,错误反馈依赖于 ICMP。
### 排查方法
- **检查服务状态**
```bash
systemctl status <service-name>
```
确认目标服务是否处于运行状态。
- **查看端口监听情况**
```bash
netstat -tuln | grep <port>
ss -tuln | grep <port>
```
检查目标主机是否在指定端口监听。
- **测试端口可达性**
```bash
telnet <ip> <port>
nc -zv <ip> <port>
```
虽然适用于 TCP,但有助于判断端口是否可达。
- **禁用防火墙进行测试**
```bash
sudo ufw disable
systemctl stop firewalld
```
临时关闭防火墙以排除干扰。
- **抓包分析**
使用 `tcpdump` 或 Wireshark 抓取网络流量,观察数据包是否到达目标主机:
```bash
tcpdump -i eth0 port <port> -nn
```
### 示例代码片段(UDP 客户端)
```c
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main() {
int sockfd;
struct sockaddr_in server_addr;
char *message = "Hello Server";
// 创建 UDP socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
// 设置服务器地址结构
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888); // 目标端口
inet_aton("192.168.1.100", &server_addr.sin_addr); // 目标 IP
// 发送数据
if (sendto(sockfd, message, strlen(message), 0,
(struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Sendto failed");
}
close(sockfd);
return 0;
}
```
---
阅读全文
相关推荐

















