123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- #!/bin/bash
- # RTSP网络连接诊断脚本
- set -e
- # 颜色定义
- RED='\033[0;31m'
- GREEN='\033[0;32m'
- YELLOW='\033[1;33m'
- NC='\033[0m' # No Color
- print_info() {
- echo -e "${GREEN}[INFO]${NC} $1"
- }
- print_warn() {
- echo -e "${YELLOW}[WARN]${NC} $1"
- }
- print_error() {
- echo -e "${RED}[ERROR]${NC} $1"
- }
- # 从配置文件读取RTSP URLs
- get_rtsp_urls() {
- if [[ -f "config.json" ]]; then
- # 使用jq解析JSON(如果可用)
- if command -v jq &> /dev/null; then
- jq -r '.streams[].rtsp_url' config.json
- else
- # 简单的grep解析
- grep -o '"rtsp://[^"]*"' config.json | sed 's/"//g'
- fi
- else
- print_error "配置文件 config.json 不存在"
- exit 1
- fi
- }
- # 测试网络连通性
- test_network_connectivity() {
- local url=$1
- print_info "测试RTSP URL: $url"
-
- # 解析URL获取主机和端口
- local host=$(echo $url | sed -n 's|rtsp://\([^:]*\):\([0-9]*\)/.*|\1|p')
- local port=$(echo $url | sed -n 's|rtsp://\([^:]*\):\([0-9]*\)/.*|\2|p')
-
- if [[ -z "$host" || -z "$port" ]]; then
- print_error "无法解析RTSP URL: $url"
- return 1
- fi
-
- print_info "主机: $host, 端口: $port"
-
- # DNS解析测试(改进的检测方法)
- print_info "测试DNS解析..."
- local dns_result=$(nslookup $host 2>/dev/null | grep -A 1 "Name:" | grep "Address:" | awk '{print $2}' | head -1)
-
- if [[ -z "$dns_result" ]]; then
- # 尝试使用dig命令
- dns_result=$(dig +short $host 2>/dev/null | head -1)
- fi
-
- if [[ -z "$dns_result" ]]; then
- # 尝试使用host命令
- dns_result=$(host $host 2>/dev/null | awk '{print $NF}' | head -1)
- fi
-
- if [[ -n "$dns_result" && "$dns_result" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
- print_info "✅ DNS解析成功"
- print_info "解析IP: $dns_result"
- else
- print_error "❌ DNS解析失败"
- print_info "调试信息: nslookup输出:"
- nslookup $host 2>&1 | sed 's/^/ /'
- return 1
- fi
-
- # 端口连通性测试(增强版)
- print_info "测试端口连通性..."
-
- # 尝试多种连接方法
- local connection_success=false
-
- # 方法1: 使用nc (netcat)
- if command -v nc >/dev/null 2>&1; then
- if timeout 10 nc -z $host $port 2>/dev/null; then
- print_info "✅ 端口 $port 可达 (nc测试)"
- connection_success=true
- fi
- fi
-
- # 方法2: 使用telnet
- if [[ "$connection_success" == "false" ]] && command -v telnet >/dev/null 2>&1; then
- if timeout 10 bash -c "echo '' | telnet $host $port" 2>/dev/null | grep -q "Connected"; then
- print_info "✅ 端口 $port 可达 (telnet测试)"
- connection_success=true
- fi
- fi
-
- # 方法3: 使用/dev/tcp (bash内置)
- if [[ "$connection_success" == "false" ]]; then
- if timeout 10 bash -c "exec 3<>/dev/tcp/$host/$port && exec 3<&-" 2>/dev/null; then
- print_info "✅ 端口 $port 可达 (bash TCP测试)"
- connection_success=true
- fi
- fi
-
- if [[ "$connection_success" == "false" ]]; then
- print_error "❌ 端口 $port 不可达"
- print_info "详细诊断:"
- print_info " - 尝试ping主机: $(ping -c 1 -W 5 $host >/dev/null 2>&1 && echo '成功' || echo '失败')"
- print_info " - 尝试traceroute: $(command -v traceroute >/dev/null && echo '可用' || echo '不可用')"
- if command -v traceroute >/dev/null 2>&1; then
- print_info "路由跟踪 (前3跳):"
- timeout 10 traceroute -m 3 $host 2>/dev/null | head -4 | sed 's/^/ /' || echo " traceroute失败"
- fi
- return 1
- fi
-
- # RTSP协议测试(简化版)
- print_info "测试RTSP协议响应..."
- if command -v nc >/dev/null 2>&1; then
- local rtsp_response=$(timeout 5 bash -c "echo -e 'OPTIONS $url RTSP/1.0\r\nCSeq: 1\r\nUser-Agent: Network-Test\r\n\r\n' | nc $host $port 2>/dev/null" || echo "")
-
- if [[ "$rtsp_response" == *"RTSP/1.0"* ]]; then
- print_info "✅ RTSP服务器响应正常"
- print_info "服务器响应: $(echo "$rtsp_response" | head -1 | tr -d '\r\n')"
- return 0
- else
- print_warn "⚠️ 端口可达但RTSP服务可能异常"
- print_info "尝试的RTSP请求无响应,可能是:"
- print_info " 1. RTSP服务器需要认证"
- print_info " 2. 服务器配置了特殊的连接要求"
- print_info " 3. 端口上运行的不是RTSP服务"
- return 0 # 端口可达就认为基本连接正常
- fi
- else
- print_info "✅ 基本连接测试通过(无法进行RTSP协议测试)"
- return 0
- fi
- }
- # 主函数
- main() {
- echo ""
- print_info "=========================================="
- print_info "RTSP网络连接诊断工具"
- print_info "=========================================="
- echo ""
-
- # 检查必要工具
- for tool in nc nslookup timeout; do
- if ! command -v $tool &> /dev/null; then
- print_error "缺少必要工具: $tool"
- print_info "请安装: apt-get install netcat-openbsd dnsutils coreutils"
- exit 1
- fi
- done
-
- # 显示网络环境信息
- print_info "网络环境信息:"
- echo " 主机名: $(hostname)"
- echo " 网络接口: $(ip route get 8.8.8.8 | awk '{print $5; exit}')"
- echo " 外网IP检测: $(timeout 5 curl -s ifconfig.me || echo "无法获取")"
- echo " DNS配置:"
- cat /etc/resolv.conf | grep nameserver | head -3 | sed 's/^/ /'
- echo ""
-
- # 获取RTSP URLs
- print_info "从配置文件读取RTSP流地址..."
- local urls=($(get_rtsp_urls))
-
- if [[ ${#urls[@]} -eq 0 ]]; then
- print_error "配置文件中未找到RTSP URL"
- exit 1
- fi
-
- print_info "找到 ${#urls[@]} 个RTSP流地址"
- echo ""
-
- # 测试每个URL
- local success_count=0
- local total_count=${#urls[@]}
-
- for url in "${urls[@]}"; do
- print_info "========== 测试流 $((success_count + 1))/$total_count =========="
- if test_network_connectivity "$url"; then
- ((success_count++))
- print_info "✅ 测试通过"
- else
- print_error "❌ 测试失败"
- fi
- echo ""
- done
-
- # 显示总结
- print_info "=========================================="
- print_info "测试完成"
- print_info "=========================================="
- print_info "成功: $success_count/$total_count"
-
- if [[ $success_count -eq $total_count ]]; then
- print_info "🎉 所有RTSP流连接测试通过!"
- print_info "如果Docker中仍无法连接,请检查:"
- print_info " 1. Docker网络模式是否为host"
- print_info " 2. 容器内DNS配置是否正确"
- print_info " 3. 防火墙设置是否阻止连接"
- else
- print_warn "⚠️ 部分RTSP流连接失败"
- print_info "建议检查:"
- print_info " 1. 网络连接状态"
- print_info " 2. RTSP服务器状态"
- print_info " 3. 防火墙配置"
- fi
-
- echo ""
- }
- # 执行主函数
- main
|