Linux 下端口占用的模拟: nc/socat

前言

今天需要测一个在写的网络辅助工具, 测试时需要预提供一些端口占用, 写了个nc脚本来实现, 这里简单技术普及下.

基础

Linux中使用nc和socat模拟端口占用的方法:

使用nc(netcat)模拟端口占用:

  1. nc -l 8080 - 监听8080端口
  2. nc -l -p 8080 - 在某些系统中需要-p参数
  3. nc -k -l 8080 - 持续监听,接受多个连接
  4. nc -l 0.0.0.0 8080 - 监听所有网卡接口

使用socat模拟端口占用:

  1. socat TCP-LISTEN:8080,fork /dev/null - 监听TCP端口
  2. socat UDP-LISTEN:8080,fork /dev/null - 监听UDP端口
  3. socat TCP-LISTEN:8080,reuseaddr,fork EXEC:/bin/cat - 可重用地址

其他工具:
用Python起HTTP服务或者脚本实现应该也是可以的, 大家可以头脑风暴.

实际使用

✅示例: 使用nc批量占用端口

#!/bin/bash
# 批量占用端口范围
start_port=8080
end_port=8090

echo "开始占用端口 $start_port$end_port"
for port in $(seq $start_port $end_port); do
    nc -l $port &
    pid=$!
    echo "端口 $port 已占用,PID: $pid"
done

echo "按Enter键查看占用情况..."
read
ss -tulpn | grep -E ":($(seq -s'|' $start_port $end_port))"

echo "按Enter键清理所有监听进程..."
read
jobs -p | xargs kill 2>/dev/null
echo "清理完成"

示例: 使用socat批量占用

#!/bin/bash
# socat批量占用指定端口列表
ports=(8080 8081 8082 9000 9001)

echo "使用socat占用端口: ${ports[*]}"
for port in "${ports[@]}"; do
    socat TCP-LISTEN:$port,reuseaddr,fork /dev/null &
    echo "端口 $port 已被socat占用,PID: $!"
done

# 显示占用情况
echo -e "\n当前端口占用情况:"
ss -tulpn | grep -E ":($(IFS='|'; echo "${ports[*]}"))"

echo -e "\n按Enter键清理所有socat进程..."
read
pkill -f "TCP-LISTEN"
echo "清理完成"

💡 注意点 & 总结

  1. 权限注意:占用1024以下端口需要root权限
  2. 工具选择
    • nc:轻量级,适合简单测试
    • socat:功能强大,适合复杂场景
    • Python:跨平台,适合脚本化测试
WARNING: Enabling and disabling experimental features do not take effect until next start of PowerShell. WARNING: Enabling and disabling experimental features do not take effect until next start of PowerShell. [PS7 19:25:05] C:\Users\Administrator\Desktop [master] > # 增强版 Install-Socat 函数(修复下载源问题) [PS7 19:25:13] C:\Users\Administrator\Desktop [master] > function Install-Socat { >> param( >> [Parameter(Mandatory = $false)] >> [string]$InstallDrive = "E:", >> >> [Parameter(Mandatory = $false)] >> [string]$InstallDir = "Program Files\Socat" >> ) >> >> # 1. 规范化路径处理 >> $fullPath = [System.IO.Path]::GetFullPath("$InstallDrive\$InstallDir").TrimEnd('\') >> >> # 2. 验证文件系统权限 >> if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { >> Write-Warning "需要管理员权限安装程序" >> return $null >> } >> >> # 3. 检查现有安装 >> $existingPath = (Get-Command socat -ErrorAction SilentlyContinue | >> Select-Object -ExpandProperty Source -First 1) ?? $null >> >> if ($existingPath) { >> Write-Host "已安装于: $existingPath" -ForegroundColor Green >> return $existingPath >> } >> >> # 4. 创建安装目录 >> try { >> if (-not (Test-Path $fullPath)) { >> $null = New-Item -Path $fullPath -ItemType Directory -Force >> } >> } catch { >> Write-Error "创建目录失败: $($_.Exception.Message)" >> return $null >> } >> >> # 5. 文件下载(更新有效的下载源) >> $tempFile = Join-Path $env:TEMP "socat-win64.zip" >> $downloadUrls = @( >> # 官方镜像源 >> "https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip", >> "https://downloads.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip?ts=$(Get-Date -UFormat %s)", >> >> # 备用镜像源 >> "https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip", >> "https://cfhcable.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip", >> "https://altushost-swe.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip" >> ) >> >> $validDownload = $false >> $lastError = $null >> >> foreach ($downloadUrl in $downloadUrls) { >> try { >> # 清除旧下载 >> if (Test-Path $tempFile) { >> Remove-Item $tempFile -Force -ErrorAction SilentlyContinue >> } >> >> # 下载文件 >> Write-Host "尝试从 $downloadUrl 下载..." -ForegroundColor Cyan >> $ProgressPreference = 'SilentlyContinue' >> >> try { >> Invoke-WebRequest $downloadUrl -OutFile $tempFile -UseBasicParsing -RetryIntervalSec 3 -ErrorAction Stop >> } catch { >> $lastError = $_.Exception.Message >> Write-Warning "下载失败 ($downloadUrl): $lastError" >> continue >> } >> >> # 验证文件大小(最小1MB) >> $fileInfo = Get-Item $tempFile -ErrorAction Stop >> if ($fileInfo.Length -lt 1MB) { >> $lastError = "文件过小 ($([math]::Round($fileInfo.Length/1KB)) KB)" >> Write-Warning "文件校验失败: $lastError" >> continue >> } >> >> # 验证ZIP文件完整性 >> try { >> Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Stop >> $archive = [System.IO.Compression.ZipFile]::OpenRead($tempFile) >> $entryCount = $archive.Entries.Count >> $archive.Dispose() >> >> if ($entryCount -eq 0) { >> $lastError = "空压缩包" >> Write-Warning "文件校验失败: $lastError" >> continue >> } >> >> $validDownload = $true >> Write-Host "成功下载并验证: $downloadUrl" -ForegroundColor Green >> break >> } catch { >> $lastError = $_.Exception.Message >> Write-Warning "文件校验失败: $lastError" >> } >> } catch { >> $lastError = $_.Exception.Message >> Write-Warning "下载过程中出错: $lastError" >> } finally { >> $ProgressPreference = 'Continue' >> } >> } >> >> if (-not $validDownload) { >> Write-Error "所有下载源均失败。最后错误: $lastError" >> Write-Host @" >> 无法自动下载socat。请手动执行以下操作: >> 1. 从以下链接下载socat: >> https://github.com/portapps/socat-portable/releases >> 2. 解压到: $fullPath >> 3. 将以下路径添加到系统PATH环境变量: >> $fullPath >> "@ -ForegroundColor Yellow >> return $null >> } >> >> # 6. 解压缩 >> try { >> # 确保目标目录存在 >> if (-not (Test-Path $fullPath)) { >> $null = New-Item -Path $fullPath -ItemType Directory -Force >> } >> >> # 使用.NET方法解压 >> Add-Type -AssemblyName System.IO.Compression.FileSystem >> [System.IO.Compression.ZipFile]::ExtractToDirectory($tempFile, $fullPath) >> >> $socatExe = Join-Path $fullPath "socat.exe" >> >> if (-not (Test-Path $socatExe -PathType Leaf)) { >> throw "解压后未找到 socat.exe" >> } >> } catch { >> Write-Error "解压失败: $($_.Exception.Message)" >> return $null >> } >> >> # 7. 环境变量更新 >> $currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine") >> if ($currentPath -notlike "*$fullPath*") { >> $newPath = $currentPath + ";$fullPath" >> [Environment]::SetEnvironmentVariable("Path", $newPath, "Machine") >> } >> >> # 8. 更新当前会话PATH >> $env:Path += ";$fullPath" >> >> # 9. 返回完整路径 >> if (Test-Path $socatExe) { >> Write-Host "socat 安装成功: $socatExe" -ForegroundColor Green >> return $socatExe.ToString() >> } else { >> Write-Error "安装后文件验证失败" >> return $null >> } >> } [PS7 19:25:14] C:\Users\Administrator\Desktop [master] > [PS7 19:25:14] C:\Users\Administrator\Desktop [master] > # 增强版 New-TcpTunnel 函数(保持不变) [PS7 19:25:14] C:\Users\Administrator\Desktop [master] > function New-TcpTunnel { >> param( >> [int]$LocalPort = 8443, >> [string]$RemoteHost = "google.com", >> [int]$RemotePort = 443, >> [string]$SocatPath = $null >> ) >> >> # 1. 获取socat路径 >> $socatBinary = if ($SocatPath -and (Test-Path $SocatPath)) { >> $SocatPath.ToString() >> } else { >> $installedPath = Install-Socat >> if (-not $installedPath) { >> throw "socat安装失败" >> } >> $installedPath.ToString() >> } >> >> # 2. 创建日志文件 >> $logTime = Get-Date -Format "yyyyMMdd-HHmmss" >> $stdOutFile = Join-Path $env:TEMP "socat-$LocalPort-$logTime-out.log" >> $stdErrFile = Join-Path $env:TEMP "socat-$LocalPort-$logTime-err.log" >> >> # 3. 启动进程 >> try { >> $processArgs = @{ >> FilePath = $socatBinary >> ArgumentList = "TCP-LISTEN:$LocalPort,fork,reuseaddr TCP:$($RemoteHost):$RemotePort" >> NoNewWindow = $true >> RedirectStandardOutput = $stdOutFile >> RedirectStandardError = $stdErrFile >> PassThru = $true >> } >> >> $process = Start-Process @processArgs >> } catch { >> Write-Error "启动socat失败: $($_.Exception.Message)" >> if (Test-Path $stdErrFile) { >> Write-Warning "错误日志内容: $(Get-Content $stdErrFile -Raw)" >> } >> throw >> } >> >> # 4. 验证端口监听 >> $portActive = $false >> 1..5 | ForEach-Object { >> Start-Sleep -Seconds 1 >> if (-not $portActive) { >> $portStatus = Get-NetTCPConnection -LocalPort $LocalPort -ErrorAction SilentlyContinue >> $portActive = [bool]$portStatus >> } >> } >> >> if (-not $portActive) { >> Write-Warning "端口 $LocalPort 状态: 未监听" >> if (Test-Path $stdErrFile) { >> Write-Warning "错误日志: $(Get-Content $stdErrFile -Raw)" >> } >> throw "隧道创建失败,端口 $LocalPort 未监听" >> } >> >> # 5. 返回进程信息 >> return [PSCustomObject]@{ >> Process = $process >> Port = $LocalPort >> StdOutLog = $stdOutFile >> StdErrLog = $stdErrFile >> } >> } [PS7 19:25:14] C:\Users\Administrator\Desktop [master] > # 测试安装函数 [PS7 19:25:20] C:\Users\Administrator\Desktop [master] > $socatPath = Install-Socat -Verbose 尝试从 https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip 下载... VERBOSE: Requested HTTP/1.1 GET with 0-byte payload VERBOSE: Received HTTP/1.1 9-byte response of content type text/plain WARNING: 下载失败 (https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip): Response status code does not indicate success: 404 (Not Found). 尝试从 https://downloads.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip?ts=1757157921 下载... VERBOSE: Requested HTTP/1.1 GET with 0-byte payload VERBOSE: Received HTTP/1.1 response of content type text/html of unknown size VERBOSE: File Name: socat-win64.zip WARNING: 文件校验失败: 文件过小 (102 KB) 尝试从 https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip 下载... VERBOSE: Requested HTTP/1.1 GET with 0-byte payload VERBOSE: Received HTTP/1.1 9-byte response of content type text/plain WARNING: 下载失败 (https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip): Response status code does not indicate success: 404 (Not Found). 尝试从 https://cfhcable.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip 下载... VERBOSE: Requested HTTP/1.1 GET with 0-byte payload WARNING: 下载失败 (https://cfhcable.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 (cfhcable.dl.sourceforge.net:443) 尝试从 https://altushost-swe.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip 下载... VERBOSE: Requested HTTP/1.1 GET with 0-byte payload VERBOSE: Received HTTP/1.1 response of content type text/html of unknown size VERBOSE: File Name: socat-win64.zip WARNING: 文件校验失败: 文件过小 (102 KB) Install-Socat: 所有下载源均失败。最后错误: 文件过小 (102 KB) 无法自动下载socat。请手动执行以下操作: 1. 从以下链接下载socat: https://github.com/portapps/socat-portable/releases 2. 解压到: E:\Program Files\Socat 3. 将以下路径添加到系统PATH环境变量: E:\Program Files\Socat [PS7 19:25:58] C:\Users\Administrator\Desktop [master] > [PS7 19:25:58] C:\Users\Administrator\Desktop [master] > # 验证安装 [PS7 19:25:58] C:\Users\Administrator\Desktop [master] > if ($socatPath) { >> socat -V >> Write-Host "socat 安装成功" -ForegroundColor Green >> } [PS7 19:25:58] C:\Users\Administrator\Desktop [master] > # 创建到HTTP服务的隧道 [PS7 19:26:10] C:\Users\Administrator\Desktop [master] > $tunnel = New-TcpTunnel -LocalPort 8080 -RemoteHost "example.com" -RemotePort 80 尝试从 https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip 下载... WARNING: 下载失败 (https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip): Response status code does not indicate success: 404 (Not Found). 尝试从 https://downloads.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip?ts=1757157971 下载... WARNING: 文件校验失败: 文件过小 (102 KB) 尝试从 https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip 下载... WARNING: 下载失败 (https://github.com/portapps/socat-portable/releases/download/1.7.4.4/socat-1.7.4.4-win64.zip): Response status code does not indicate success: 404 (Not Found). 尝试从 https://cfhcable.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip 下载... WARNING: 下载失败 (https://cfhcable.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip): 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 (cfhcable.dl.sourceforge.net:443) 尝试从 https://altushost-swe.dl.sourceforge.net/project/unix-utils/socat/1.7.4.4/socat-1.7.4.4-win64.zip 下载... WARNING: 文件校验失败: 文件过小 (102 KB) Install-Socat: Line | 13 | $installedPath = Install-Socat | ~~~~~~~~~~~~~ | 所有下载源均失败。最后错误: 文件过小 (102 KB) 无法自动下载socat。请手动执行以下操作: 1. 从以下链接下载socat: https://github.com/portapps/socat-portable/releases 2. 解压到: E:\Program Files\Socat 3. 将以下路径添加到系统PATH环境变量: E:\Program Files\Socat Exception: Line | 15 | throw "socat安装失败" | ~~~~~~~~~~~~~~~~~ | socat安装失败 [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > # 测试隧道 [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > Start-Process "http://localhost:$($tunnel.Port)" [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > # 监控日志 [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > Get-Content $tunnel.StdErrLog -Wait -Tail 10 Get-Content: Cannot bind argument to parameter 'Path' because it is null. [PS7 19:26:48] C:\Users\Administrator\Desktop [master] > $cacheFile = "C:\ProgramData\socat-cache\socat-win64.zip" [PS7 19:27:07] C:\Users\Administrator\Desktop [master] > if (Test-Path $cacheFile) { >> Copy-Item $cacheFile $tempFile >> $validDownload = $true >> } [PS7 19:27:07] C:\Users\Administrator\Desktop [master] >
最新发布
09-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值